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

Integration Candidate: 2020-11-10 #652

Merged
merged 7 commits into from
Nov 16, 2020
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
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,15 @@ The autogenerated OSAL user's guide can be viewed at <https://github.com/nasa/cF

## Version History

### Development Build: 5.1.0-rc1+dev75

- Ensure that the handle is not NULL before invoking dlclose(). In particular the handle will be NULL for static modules. Shutdown after CTRL+C occurs normally (no segfault).
- Add a "flags" parameter to OS_ModuleLoad() to indicate the desired symbol visibility:
- GLOBAL (0, the default, and matches current behavior)
- LOCAL which hides from other modules and prevents other modules from binding to symbols in this module, thereby ensuring/preserving the ability to unload in the future
- CFE should use LOCAL flag for apps, and GLOBAL flags for libraries.
- See <https://github.com/nasa/osal/pull/652>

### Development Build: 5.1.0-rc1+dev68

- When `OS_DEBUG` is enabled, this adds a message if mutex give/take actions occur outside the expected sequence. This informs the user (via the debug console) if a lock is taken more than once or if a lock is given by a different task than the one that originally took it:
Expand Down
64 changes: 63 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 *symbol_address, const char *symbol_name);

/*-------------------------------------------------------------------------------------*/
/**
* @brief Dumps the system symbol table to a file
Expand All @@ -127,9 +184,14 @@ int32 OS_SymbolTableDump(const char *filename, uint32 size_limit);
*
* Loads an object file into the running operating system
*
* The "flags" parameter may influence how the loaded module symbols are made
* available for use in the application. See #OS_MODULE_FLAG_LOCAL_SYMBOLS
* and #OS_MODULE_FLAG_GLOBAL_SYMBOLS for descriptions.
*
* @param[out] module_id Non-zero OSAL ID corresponding to the loaded module
* @param[in] module_name Name of module
* @param[in] filename File containing the object code to load
* @param[in] flags Options for the loaded module
*
* @return Execution status, see @ref OSReturnCodes
* @retval #OS_SUCCESS @copybrief OS_SUCCESS
Expand All @@ -138,7 +200,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
2 changes: 1 addition & 1 deletion src/os/inc/osapi-version.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
/*
* Development Build Macro Definitions
*/
#define OS_BUILD_NUMBER 67
#define OS_BUILD_NUMBER 75
#define OS_BUILD_BASELINE "v5.1.0-rc1"

/*
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
32 changes: 25 additions & 7 deletions src/os/shared/inc/os-shared-module.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,20 @@

#include <os-shared-globaldefs.h>

typedef enum
{
OS_MODULE_TYPE_UNKNOWN = 0, /**< Default/unspecified (reserved value) */
OS_MODULE_TYPE_DYNAMIC = 1, /**< Module is dynamically loaded via the OS loader */
OS_MODULE_TYPE_STATIC = 2 /**< Module is statically linked and is a placeholder */
} OS_module_type_t;

typedef struct
{
char module_name[OS_MAX_API_NAME];
char file_name[OS_MAX_PATH_LEN];
uint32 flags;
cpuaddr entry_point;
char module_name[OS_MAX_API_NAME];
char file_name[OS_MAX_PATH_LEN];
OS_module_type_t module_type;
uint32 flags;
cpuaddr entry_point;
} OS_module_internal_record_t;

/*
Expand Down Expand Up @@ -85,15 +93,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 +127,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