Skip to content

Commit 8a9e736

Browse files
authored
Merge pull request #643 from jphickey/fix-641-moduleload-flags
Fix #641, add OS_ModuleLoad flags
2 parents f2f1f44 + a32392a commit 8a9e736

File tree

17 files changed

+464
-71
lines changed

17 files changed

+464
-71
lines changed

src/os/inc/osapi-os-loader.h

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,44 @@
3434
** Defines
3535
*/
3636

37+
/**
38+
* @brief Requests OS_ModuleLoad() to add the symbols to the global symbol table
39+
*
40+
* When supplied as the "flags" argument to OS_ModuleLoad(), this indicates
41+
* that the symbols in the loaded module should be added to the global symbol
42+
* table. This will make symbols in this library available for use when
43+
* resolving symbols in future module loads.
44+
*
45+
* This is the default mode of operation for OS_ModuleLoad().
46+
*
47+
* @note On some operating systems, use of this option may make it difficult
48+
* to unload the module in the future, if the symbols are in use by other entities.
49+
*
50+
*/
51+
#define OS_MODULE_FLAG_GLOBAL_SYMBOLS 0x00
52+
53+
/**
54+
* @brief Requests OS_ModuleLoad() to keep the symbols local/private to this module
55+
*
56+
* When supplied as the "flags" argument to OS_ModuleLoad(), this indicates
57+
* that the symbols in the loaded module should NOT be added to the global
58+
* symbol table. This means the symbols in the loaded library will not available
59+
* to for use by other modules.
60+
*
61+
* Use this option is recommended for cases where no other entities will need
62+
* to reference symbols within this module. This helps ensure that the module
63+
* can be more safely unloaded in the future, by preventing other modules from
64+
* binding to it. It also helps reduce the likelihood of symbol name conflicts
65+
* among modules.
66+
*
67+
* @note To look up symbols within a module loaded with this flag, use
68+
* OS_SymbolLookupInModule() instead of OS_SymbolLookup(). Also note that
69+
* references obtained using this method are not tracked by the OS; the
70+
* application must ensure that all references obtained in this manner have
71+
* been cleaned up/released before unloading the module.
72+
*/
73+
#define OS_MODULE_FLAG_LOCAL_SYMBOLS 0x01
74+
3775
/*
3876
** Typedefs
3977
*/
@@ -105,6 +143,25 @@ typedef const struct
105143
*/
106144
int32 OS_SymbolLookup(cpuaddr *symbol_address, const char *symbol_name);
107145

146+
/*-------------------------------------------------------------------------------------*/
147+
/**
148+
* @brief Find the Address of a Symbol within a module
149+
*
150+
* This is similar to OS_SymbolLookup() but for a specific module ID.
151+
* This should be used to look up a symbol in a module that has been
152+
* loaded with the #OS_MODULE_FLAG_LOCAL_SYMBOLS flag.
153+
*
154+
* @param[in] module_id Module ID that should contain the symbol
155+
* @param[out] symbol_address Set to the address of the symbol
156+
* @param[in] symbol_name Name of the symbol to look up
157+
*
158+
* @return Execution status, see @ref OSReturnCodes
159+
* @retval #OS_SUCCESS @copybrief OS_SUCCESS
160+
* @retval #OS_ERROR if the symbol could not be found
161+
* @retval #OS_INVALID_POINTER if one of the pointers passed in are NULL
162+
*/
163+
int32 OS_ModuleSymbolLookup(osal_id_t module_id, cpuaddr *SymbolAddress, const char *SymbolName);
164+
108165
/*-------------------------------------------------------------------------------------*/
109166
/**
110167
* @brief Dumps the system symbol table to a file
@@ -138,7 +195,7 @@ int32 OS_SymbolTableDump(const char *filename, uint32 size_limit);
138195
* @retval #OS_ERR_NO_FREE_IDS if the module table is full
139196
* @retval #OS_ERR_NAME_TAKEN if the name is in use
140197
*/
141-
int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *filename);
198+
int32 OS_ModuleLoad(osal_id_t *module_id, const char *module_name, const char *filename, uint32 flags);
142199

143200
/*-------------------------------------------------------------------------------------*/
144201
/**

src/os/portable/os-impl-no-symtab.c

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,17 +32,31 @@
3232

3333
/*----------------------------------------------------------------
3434
*
35-
* Function: OS_SymbolLookup_Impl
35+
* Function: OS_GlobalSymbolLookup_Impl
3636
*
3737
* Purpose: Implemented per internal OSAL API
3838
* See prototype for argument/return detail
3939
*
4040
*-----------------------------------------------------------------*/
41-
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
41+
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
4242
{
4343
return OS_ERR_NOT_IMPLEMENTED;
4444

45-
} /* end OS_SymbolLookup_Impl */
45+
} /* end OS_GlobalSymbolLookup_Impl */
46+
47+
/*----------------------------------------------------------------
48+
*
49+
* Function: OS_ModuleSymbolLookup_Impl
50+
*
51+
* Purpose: Implemented per internal OSAL API
52+
* See prototype for argument/return detail
53+
*
54+
*-----------------------------------------------------------------*/
55+
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName)
56+
{
57+
return OS_ERR_NOT_IMPLEMENTED;
58+
59+
} /* end OS_ModuleSymbolLookup_Impl */
4660

4761
/*----------------------------------------------------------------
4862
*

src/os/portable/os-impl-posix-dl-loader.c

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,38 @@
6464
int32 OS_ModuleLoad_Impl(uint32 module_id, const char *translated_path)
6565
{
6666
int32 status = OS_ERROR;
67+
int dl_mode;
68+
69+
/*
70+
* RTLD_NOW should instruct dlopen() to resolve all the symbols in the
71+
* module immediately, as opposed to waiting until they are used.
72+
* The latter (lazy mode) is non-deterministic - a resolution error on
73+
* a rarely-used symbol could cause a random failure far in the future.
74+
*/
75+
dl_mode = RTLD_NOW;
76+
77+
if ((OS_module_table[module_id].flags & OS_MODULE_FLAG_LOCAL_SYMBOLS) != 0)
78+
{
79+
/*
80+
* Do not add the symbols in this module to the global symbol table.
81+
* This mode helps prevent any unanticipated references into this
82+
* module, which can in turn prevent unloading via dlclose().
83+
*/
84+
dl_mode |= RTLD_LOCAL;
85+
}
86+
else
87+
{
88+
/*
89+
* Default mode - add symbols to the global symbol table, so they
90+
* will be available to resolve symbols in future module loads.
91+
* However, any such references will prevent unloading of this
92+
* module via dlclose().
93+
*/
94+
dl_mode |= RTLD_GLOBAL;
95+
}
6796

6897
dlerror();
69-
OS_impl_module_table[module_id].dl_handle = dlopen(translated_path, RTLD_NOW | RTLD_GLOBAL);
98+
OS_impl_module_table[module_id].dl_handle = dlopen(translated_path, dl_mode);
7099
if (OS_impl_module_table[module_id].dl_handle != NULL)
71100
{
72101
status = OS_SUCCESS;

src/os/portable/os-impl-posix-dl-symtab.c

Lines changed: 55 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -78,23 +78,25 @@
7878

7979
/*----------------------------------------------------------------
8080
*
81-
* Function: OS_SymbolLookup_Impl
81+
* Function: OS_GenericSymbolLookup_Impl
8282
*
8383
* Purpose: Implemented per internal OSAL API
8484
* See prototype for argument/return detail
8585
*
8686
*-----------------------------------------------------------------*/
87-
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
87+
int32 OS_GenericSymbolLookup_Impl(void *dl_handle, cpuaddr *SymbolAddress, const char *SymbolName)
8888
{
89-
int32 status = OS_ERROR;
9089
const char *dlError; /* Pointer to error string */
91-
void * Function;
90+
void *Function;
91+
int32 status;
92+
93+
status = OS_ERROR;
9294

9395
/*
9496
* call dlerror() to clear any prior error that might have occurred.
9597
*/
9698
dlerror();
97-
Function = dlsym(OSAL_DLSYM_DEFAULT_HANDLE, SymbolName);
99+
Function = dlsym(dl_handle, SymbolName);
98100
dlError = dlerror();
99101

100102
/*
@@ -110,16 +112,61 @@ int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
110112
* and as such all valid symbols should be non-NULL, so NULL is considered
111113
* an error even if the C library doesn't consider this an error.
112114
*/
113-
if (dlError == NULL && Function != NULL)
115+
if (dlError != NULL)
116+
{
117+
OS_DEBUG("Error: %s: %s\n", SymbolName, dlError);
118+
}
119+
else if (Function == NULL)
120+
{
121+
/* technically not an error per POSIX, but in practice should not happen */
122+
OS_DEBUG("Error: %s: dlsym() returned NULL\n", SymbolName);
123+
}
124+
else
114125
{
115-
*SymbolAddress = (cpuaddr)Function;
116-
status = OS_SUCCESS;
126+
status = OS_SUCCESS;
117127
}
118128

129+
*SymbolAddress = (cpuaddr)Function;
130+
131+
return status;
132+
}
133+
134+
/*----------------------------------------------------------------
135+
*
136+
* Function: OS_GlobalSymbolLookup_Impl
137+
*
138+
* Purpose: Implemented per internal OSAL API
139+
* See prototype for argument/return detail
140+
*
141+
*-----------------------------------------------------------------*/
142+
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName)
143+
{
144+
int32 status;
145+
146+
status = OS_GenericSymbolLookup_Impl(OSAL_DLSYM_DEFAULT_HANDLE, SymbolAddress, SymbolName);
147+
119148
return status;
120149

121150
} /* end OS_SymbolLookup_Impl */
122151

152+
/*----------------------------------------------------------------
153+
*
154+
* Function: OS_ModuleSymbolLookup_Impl
155+
*
156+
* Purpose: Implemented per internal OSAL API
157+
* See prototype for argument/return detail
158+
*
159+
*-----------------------------------------------------------------*/
160+
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName)
161+
{
162+
int32 status;
163+
164+
status = OS_GenericSymbolLookup_Impl(OS_impl_module_table[local_id].dl_handle, SymbolAddress, SymbolName);
165+
166+
return status;
167+
168+
} /* end OS_ModuleSymbolLookup_Impl */
169+
123170
/*----------------------------------------------------------------
124171
*
125172
* Function: OS_SymbolTableDump_Impl

src/os/shared/inc/os-shared-module.h

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -93,15 +93,25 @@ int32 OS_ModuleUnload_Impl(uint32 module_id);
9393
------------------------------------------------------------------*/
9494
int32 OS_ModuleGetInfo_Impl(uint32 module_id, OS_module_prop_t *module_prop);
9595

96+
/*----------------------------------------------------------------
97+
Function: OS_GlobalSymbolLookup_Impl
98+
99+
Purpose: Find the Address of a Symbol in the global symbol table.
100+
The address of the symbol will be stored in the pointer that is passed in.
101+
102+
Returns: OS_SUCCESS on success, or relevant error code
103+
------------------------------------------------------------------*/
104+
int32 OS_GlobalSymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName);
105+
96106
/*----------------------------------------------------------------
97107
Function: OS_SymbolLookup_Impl
98108
99-
Purpose: Find the Address of a Symbol
109+
Purpose: Find the Address of a Symbol within a specific module.
100110
The address of the symbol will be stored in the pointer that is passed in.
101111
102112
Returns: OS_SUCCESS on success, or relevant error code
103113
------------------------------------------------------------------*/
104-
int32 OS_SymbolLookup_Impl(cpuaddr *SymbolAddress, const char *SymbolName);
114+
int32 OS_ModuleSymbolLookup_Impl(uint32 local_id, cpuaddr *SymbolAddress, const char *SymbolName);
105115

106116
/*----------------------------------------------------------------
107117
Function: OS_SymbolTableDump_Impl
@@ -117,6 +127,6 @@ int32 OS_SymbolTableDump_Impl(const char *filename, uint32 size_limit);
117127
* These need to be exposed for unit testing
118128
*/
119129
int32 OS_ModuleLoad_Static(const char *ModuleName);
120-
int32 OS_SymbolLookup_Static(cpuaddr *SymbolAddress, const char *SymbolName);
130+
int32 OS_SymbolLookup_Static(cpuaddr *SymbolAddress, const char *SymbolName, const char *ModuleName);
121131

122132
#endif /* INCLUDE_OS_SHARED_MODULE_H_ */

0 commit comments

Comments
 (0)