Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix #641, add OS_ModuleLoad flags #643

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 58 additions & 1 deletion src/os/inc/osapi-os-loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,44 @@
** Defines
*/

/**
* @brief Requests OS_ModuleLoad() to add the symbols to the global symbol table
*
* When supplied as the "flags" argument to OS_ModuleLoad(), this indicates
* that the symbols in the loaded module should be added to the global symbol
* table. This will make symbols in this library available for use when
* resolving symbols in future module loads.
*
* This is the default mode of operation for OS_ModuleLoad().
*
* @note On some operating systems, use of this option may make it difficult
* to unload the module in the future, if the symbols are in use by other entities.
*
*/
#define OS_MODULE_FLAG_GLOBAL_SYMBOLS 0x00

/**
* @brief Requests OS_ModuleLoad() to keep the symbols local/private to this module
*
* When supplied as the "flags" argument to OS_ModuleLoad(), this indicates
* that the symbols in the loaded module should NOT be added to the global
* symbol table. This means the symbols in the loaded library will not available
* to for use by other modules.
*
* Use this option is recommended for cases where no other entities will need
* to reference symbols within this module. This helps ensure that the module
* can be more safely unloaded in the future, by preventing other modules from
* binding to it. It also helps reduce the likelihood of symbol name conflicts
* among modules.
*
* @note To look up symbols within a module loaded with this flag, use
* OS_SymbolLookupInModule() instead of OS_SymbolLookup(). Also note that
* references obtained using this method are not tracked by the OS; the
* application must ensure that all references obtained in this manner have
* been cleaned up/released before unloading the module.
*/
#define OS_MODULE_FLAG_LOCAL_SYMBOLS 0x01

/*
** Typedefs
*/
Expand Down Expand Up @@ -105,6 +143,25 @@ typedef const struct
*/
int32 OS_SymbolLookup(cpuaddr *symbol_address, const char *symbol_name);

/*-------------------------------------------------------------------------------------*/
/**
* @brief Find the Address of a Symbol within a module
*
* This is similar to OS_SymbolLookup() but for a specific module ID.
* This should be used to look up a symbol in a module that has been
* loaded with the #OS_MODULE_FLAG_LOCAL_SYMBOLS flag.
*
* @param[in] module_id Module ID that should contain the symbol
* @param[out] symbol_address Set to the address of the symbol
* @param[in] symbol_name Name of the symbol to look up
*
* @return Execution status, see @ref OSReturnCodes
* @retval #OS_SUCCESS @copybrief OS_SUCCESS
* @retval #OS_ERROR if the symbol could not be found
* @retval #OS_INVALID_POINTER if one of the pointers passed in are NULL
*/
int32 OS_ModuleSymbolLookup(osal_id_t module_id, cpuaddr *SymbolAddress, const char *SymbolName);

/*-------------------------------------------------------------------------------------*/
/**
* @brief Dumps the system symbol table to a file
Expand Down Expand Up @@ -138,7 +195,7 @@ int32 OS_SymbolTableDump(const char *filename, uint32 size_limit);
* @retval #OS_ERR_NO_FREE_IDS if the module table is full
* @retval #OS_ERR_NAME_TAKEN if the name is in use
*/
int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *filename);
int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *filename, uint32 flags);

/*-------------------------------------------------------------------------------------*/
/**
Expand Down
20 changes: 17 additions & 3 deletions src/os/portable/os-impl-no-symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,31 @@

/*----------------------------------------------------------------
*
* Function: OS_SymbolLookup_Impl
* Function: OS_GlobalSymbolLookup_Impl
*
* Purpose: Implemented per internal OSAL API
* See prototype for argument/return detail
*
*-----------------------------------------------------------------*/
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
{
return OS_ERR_NOT_IMPLEMENTED;

} /* end OS_SymbolLookup_Impl */
} /* end OS_GlobalSymbolLookup_Impl */

/*----------------------------------------------------------------
*
* Function: OS_ModuleSymbolLookup_Impl
*
* Purpose: Implemented per internal OSAL API
* See prototype for argument/return detail
*
*-----------------------------------------------------------------*/
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName)
{
return OS_ERR_NOT_IMPLEMENTED;

} /* end OS_ModuleSymbolLookup_Impl */

/*----------------------------------------------------------------
*
Expand Down
31 changes: 30 additions & 1 deletion src/os/portable/os-impl-posix-dl-loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,38 @@
int32 OS_ModuleLoad_Impl(uint32 module_id, const char *translated_path)
{
int32 status = OS_ERROR;
int dl_mode;

/*
* RTLD_NOW should instruct dlopen() to resolve all the symbols in the
* module immediately, as opposed to waiting until they are used.
* The latter (lazy mode) is non-deterministic - a resolution error on
* a rarely-used symbol could cause a random failure far in the future.
*/
dl_mode = RTLD_NOW;

if ((OS_module_table[module_id].flags & OS_MODULE_FLAG_LOCAL_SYMBOLS) != 0)
{
/*
* Do not add the symbols in this module to the global symbol table.
* This mode helps prevent any unanticipated references into this
* module, which can in turn prevent unloading via dlclose().
*/
dl_mode |= RTLD_LOCAL;
}
else
{
/*
* Default mode - add symbols to the global symbol table, so they
* will be available to resolve symbols in future module loads.
* However, any such references will prevent unloading of this
* module via dlclose().
*/
dl_mode |= RTLD_GLOBAL;
}

dlerror();
OS_impl_module_table[module_id].dl_handle = dlopen(translated_path, RTLD_NOW | RTLD_GLOBAL);
OS_impl_module_table[module_id].dl_handle = dlopen(translated_path, dl_mode);
if (OS_impl_module_table[module_id].dl_handle != NULL)
{
status = OS_SUCCESS;
Expand Down
63 changes: 55 additions & 8 deletions src/os/portable/os-impl-posix-dl-symtab.c
Original file line number Diff line number Diff line change
Expand Up @@ -78,23 +78,25 @@

/*----------------------------------------------------------------
*
* Function: OS_SymbolLookup_Impl
* Function: OS_GenericSymbolLookup_Impl
*
* Purpose: Implemented per internal OSAL API
* See prototype for argument/return detail
*
*-----------------------------------------------------------------*/
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
int32 OS_GenericSymbolLookup_Impl(void *dl_handle, cpuaddr *SymbolAddress, const char *SymbolName)
{
int32 status = OS_ERROR;
const char *dlError; /* Pointer to error string */
void * Function;
void *Function;
int32 status;

status = OS_ERROR;

/*
* call dlerror() to clear any prior error that might have occurred.
*/
dlerror();
Function = dlsym(OSAL_DLSYM_DEFAULT_HANDLE, SymbolName);
Function = dlsym(dl_handle, SymbolName);
dlError = dlerror();

/*
Expand All @@ -110,16 +112,61 @@ int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
* and as such all valid symbols should be non-NULL, so NULL is considered
* an error even if the C library doesn't consider this an error.
*/
if (dlError == NULL && Function != NULL)
if (dlError != NULL)
{
OS_DEBUG("Error: %s: %s\n", SymbolName, dlError);
}
else if (Function == NULL)
{
/* technically not an error per POSIX, but in practice should not happen */
OS_DEBUG("Error: %s: dlsym() returned NULL\n", SymbolName);
}
else
{
*SymbolAddress = (cpuaddr)Function;
status = OS_SUCCESS;
status = OS_SUCCESS;
}

*SymbolAddress = (cpuaddr)Function;

return status;
}

/*----------------------------------------------------------------
*
* Function: OS_GlobalSymbolLookup_Impl
*
* Purpose: Implemented per internal OSAL API
* See prototype for argument/return detail
*
*-----------------------------------------------------------------*/
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
{
int32 status;

status = OS_GenericSymbolLookup_Impl(OSAL_DLSYM_DEFAULT_HANDLE, SymbolAddress, SymbolName);

return status;

} /* end OS_SymbolLookup_Impl */

/*----------------------------------------------------------------
*
* Function: OS_ModuleSymbolLookup_Impl
*
* Purpose: Implemented per internal OSAL API
* See prototype for argument/return detail
*
*-----------------------------------------------------------------*/
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName)
{
int32 status;

status = OS_GenericSymbolLookup_Impl(OS_impl_module_table[local_id].dl_handle, SymbolAddress, SymbolName);

return status;

} /* end OS_ModuleSymbolLookup_Impl */

/*----------------------------------------------------------------
*
* Function: OS_SymbolTableDump_Impl
Expand Down
16 changes: 13 additions & 3 deletions src/os/shared/inc/os-shared-module.h
Original file line number Diff line number Diff line change
Expand Up @@ -85,15 +85,25 @@ int32 OS_ModuleUnload_Impl(uint32 module_id);
------------------------------------------------------------------*/
int32 OS_ModuleGetInfo_Impl(uint32 module_id, OS_module_prop_t *module_prop);

/*----------------------------------------------------------------
Function: OS_GlobalSymbolLookup_Impl

Purpose: Find the Address of a Symbol in the global symbol table.
The address of the symbol will be stored in the pointer that is passed in.

Returns: OS_SUCCESS on success, or relevant error code
------------------------------------------------------------------*/
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName);

/*----------------------------------------------------------------
Function: OS_SymbolLookup_Impl

Purpose: Find the Address of a Symbol
Purpose: Find the Address of a Symbol within a specific module.
The address of the symbol will be stored in the pointer that is passed in.

Returns: OS_SUCCESS on success, or relevant error code
------------------------------------------------------------------*/
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName);
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName);

/*----------------------------------------------------------------
Function: OS_SymbolTableDump_Impl
Expand All @@ -109,6 +119,6 @@ int32 OS_SymbolTableDump_Impl(const char *filename, uint32 size_limit);
* These need to be exposed for unit testing
*/
int32 OS_ModuleLoad_Static(const char *ModuleName);
int32 OS_SymbolLookup_Static(cpuaddr *SymbolAddress, const char *SymbolName);
int32 OS_SymbolLookup_Static(cpuaddr *SymbolAddress, const char *SymbolName, const char *ModuleName);

#endif /* INCLUDE_OS_SHARED_MODULE_H_ */
Loading