/* * (c) Copyright, Real-Time Innovations, 2007-2024. * All rights reserved. * * No duplications, whole or partial, manual or electronic, may be made * without express written permission. Any such copies, or * revisions thereof, must display this notice unaltered. * This code contains trade secrets of Real-Time Innovations, Inc. */ #ifndef osapi_library_h #define osapi_library_h /** @internal \file * \brief Library utilities */ /** @internal \defgroup RTIOsapiLibraryClass RTIOsapiLibrary * \ingroup RTIOsapiModule * * \brief OS-independent way to load a library at run-time */ #include "osapi/osapi_type.h" #include "osapi/osapi_dll.h" #if (defined(RTI_LINUX) || defined(RTI_SOL2) || defined(RTI_AIX) \ || defined(RTI_DARWIN)) #include #endif #if (defined(RTI_LINUX) || defined(RTI_SOL2) || defined(RTI_AIX) \ || defined(RTI_DARWIN)) /* RTLD_LAZY and RTLD_NOW are already defined */ #else #define RTLD_LAZY 1 #define RTLD_NOW 2 #endif #ifndef RTI_UNIX_DL #if (defined(RTI_LINUX) || defined(RTI_SOL2) || defined(RTI_AIX) \ || defined(RTI_DARWIN) || defined(RTI_QNX) || defined(RTI_VXWORKS_DL)) \ && (ENABLE_FACE_COMPLIANCE == FACE_COMPLIANCE_LEVEL_NONE) #define RTI_UNIX_DL #if defined(RTI_DARWIN) #define RTI_DYLIB_FILE_EXTENSION ".dylib" #else #define RTI_DYLIB_FILE_EXTENSION ".so" #endif #endif #endif /** @internal \ingroup RTIOsapiLibraryClass \brief Whith this mode, the references to the library symbols are resolved when the code that references them is executed. */ #define RTI_OSAPI_LIBRARY_RTLD_LAZY RTLD_LAZY /** @internal \ingroup RTIOsapiLibraryClass \brief Whith this mode, all the undefined symbols in the library are resolved before RTIOsapiLibrary_open returns. */ #define RTI_OSAPI_LIBRARY_RTLD_NOW RTLD_NOW /* * RTLD_DEEPBIND flag is used to force the dynamic linker to load symbols from * the library before global ones. * * SEC-2376: The Security Plugins library requires this flag to avoid conflicts * when it is loaded by some Python distributions that have a built-in version * of OpenSSL. * * This flag is only supported in Linux. * * The flag cannot be used when AddressSanitizer is enabled as a consequence of * a bug in the Sanitizer itself. * * In Android, we cannot use the RTLD_DEEPBIND flag as it's not defined in the * Android header files. */ #if defined(RTI_LINUX) && !defined(RTI_ANDROID) \ && !defined(RTI_ADDRESS_SANITIZER_IS_ENABLED) #define RTI_OSAPI_LIBRARY_RTLD_DEEPBIND RTLD_DEEPBIND #else #define RTI_OSAPI_LIBRARY_RTLD_DEEPBIND 0 #endif /** @internal \ingroup RTIOsapiLibraryClass \brief Defines the architectures that support loading dynamic libraries. */ #ifndef RTI_OSAPI_DYNAMIC_LIBRARY_LOADING_SUPPORT #if defined(RTI_UNIX_DL) || defined(RTI_WIN32) || defined(RTI_INTIME) #define RTI_OSAPI_DYNAMIC_LIBRARY_LOADING_SUPPORT #endif #endif #ifdef __cplusplus extern "C" { #endif /** @internal \ingroup RTIOsapiLibraryClass * \brief Completes (if necessary) the name of a shared library file * * For example: (original_name -> unix_name / windows_name) * dir/mystuff -> dir/libmystuff.so / dir/mystuff.dll * dir/mystuff.x -> dir/libmystuff.x / dir/mystuff.x * dir/libmystuff -> dir/libmystuff.so / dir/libmystuff.dll * dir/libmystuff.dll -> dir/libmystuff.dll / dir/libmystuff.dll * * \param fileName (OUT) The resulting path. With the prefix/extension * if needed. The caller must allocate this memory. Note * that this string will be at most 9 bytes longer than * 'libraryName'. * \param fileNameBufSize The capacity of fileName's buffer, including NUL. * \param libraryName The input path. * \param autoAppendDebugModifier If we're running debug libraries, and the * given libraryName is not yet fully * specified, and this flag is set to true, * automatically append 'd'. */ extern RTIOsapiDllExport RTIBool RTIOsapiLibrary_getFullSharedLibraryName( char *fileName, size_t fileNameBufSize, const char *libraryName, RTIBool autoAppendDebugModifier); /** @internal \ingroup RTIOsapiLibraryClass * \brief Makes the library specified by fileName available to the calling * program. * * \pre fileName is not NULL. * * \param libraryName \st_in. Library file name. This can be the filename of * the library such as librtimonitoring.so, or the name of the library such as * rtimonitoring. If a string that does not have a .so (linux) or .dll * extension is encountered the function will append/prepend the necessary * characters before trying to load the library. \param mode \st_in. One of the * following values must be included in mode:
* - RTI_OSAPI_LIBRARY_RTLD_LAZY [Not valid in Windows] Perform lazy binding. * Only resolves symbols as the code that references is executed. If the * symbol is never referenced, then is never resolved.
* - RTI_OSAPI_LIBRARY_RTLD_NOW All the undefined symbols in the library are * resolved before RTIOsapiLibrary_open returns. If this cannot be done an * error is returned.
* * \return Opaque handle for the dynamic library or NULL if there is * an error. */ extern RTIOsapiDllExport void *RTIOsapiLibrary_open( const char *libraryName, int mode); /** @internal \ingroup RTIOsapiLibraryClass * \brief Same as RTIOsapiLibrary_open, except never append a debugModifier * to the libraryName before loading it. Use this function for libraries that * RTI typically does not ship. * * \pre fileName is not NULL. * * \param libraryName \st_in. Library file name. * * \return Opaque handle for the dynamic library or NULL if there is * an error. */ extern RTIOsapiDllExport void *RTIOsapiLibrary_openNoDebugModifier( const char *libraryName, int mode); /** @internal \ingroup RTIOsapiLibraryClass * \brief Makes the library specified by fileName available to the calling * program. * * \pre fileName is not NULL. * * \param libraryName \st_in. Library file name. This can be the filename of * the library such as librtimonitoring.so, or the name of the library such as * rtimonitoring. If a string that does not have a .so (linux) or .dll extension * is encountered the function will append/prepend the necessary characters * before trying to load the library. \param mode \st_in. One of the following * values must be included in mode:
* - RTI_OSAPI_LIBRARY_RTLD_LAZY [Not valid in Windows] Perform lazy binding. * Only resolves symbols as the code that references is executed. If the symbol * is never referenced, then is never resolved.
* - RTI_OSAPI_LIBRARY_RTLD_NOW All the undefined symbols in the library are * resolved before RTIOsapiLibrary_open returns. If this connot be done an error * is returned.
\param \st_in autoAppendDebugModifier automatically appends * the debug suffix to the library name if specified. \param \st_in logError * indicates whether or not to log messages when any errors occur. \return * Opaque handle for the dynamic library or NULL if there is an error. */ extern RTIOsapiDllExport void *RTIOsapiLibrary_openEx( const char *libraryName, int mode, RTIBool autoAppendDebugModifier, RTIBool logError); /** @internal \ingroup RTIOsapiLibraryClass * \brief Closes a dynamic library previously opened with * RTIOsapiLibrary_open. * * \pre handle is not NULL. * * \param handle \st_in. Dynamic library handle. * * \return 0 on success, and non-zero on error. */ extern RTIOsapiDllExport int RTIOsapiLibrary_close(void *handle); /** @internal \ingroup RTIOsapiLibraryClass * \brief Takes a handle of a dynamic library returned by * RTIOsapiLibrary_open, returning the address where a symbol is loaded into * memory. * * If the symbol is not found in the specified library * RTIOsapiLibrary_getSymbolAddress returns NULL. * * \pre handle is not NULL. * * \param handle \st_in. Dynamic library handle. * \param symbol \st_in. Symbol name. * * \return Addess of the new symbol on success, and NULL on error. */ extern RTIOsapiDllExport void *RTIOsapiLibrary_getSymbolAddress( void *handle, const char *symbol); /** @internal \ingroup RTIOsapiLibraryClass * @brief Check if the Core Library is compiled dynamically or statically. * @return TRUE if Core library is compiled dynamically and FALSE if Core * library is compiled statically. */ extern RTIOsapiDllExport RTIBool RTIOsapiLibrary_isSharedLibrary(void); /** @internal \ingroup RTIOsapiLibraryClass * @brief Check if the current architecture supports loading of dynamic * libraries. * @return RTI_TRUE if loading libraries dynamically is supported and RTI_FALSE * if loading libraries dynamically is not supported. */ extern RTIOsapiDllExport RTIBool RTIOsapiLibrary_isDynamicLibraryLoadingSupported(void); #ifdef __cplusplus } /* extern "C" */ #endif #endif /* osapi_library_h */