I am using certain GNU tools, i.e. the GNU C++ Compiler (g++) and the GNU Linker (ld) to create a shared library (.so) file as well as a binary executable file.
The binary executable file makes use of the dlopen
function to dynamically load the shared library file at runtime. In addition to this, the shared library file
needs to invoke a particular class method (called ToolboxManager::registerToolbox
) which is defined within the binary executable. This is accommodated by forcing the binary
executable to export the class method, which in turn is accomplished at link time by linking the binary executable with the following command line options ;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
where the file ${top_srcdir}/dynamic_symbol_table.txt
contains the following content ;
{
extern "C++"
{
"ToolboxManager::registerToolbox*";
};
};
Note the use of the asterisk (*) in the file to force the linker to export all symbols that begin with ToolboxManager::registerToolbox
.
When I run the GNU nm utility (nm -C -g ./a.out
) on the resulting binary executable, it displays the following information about the afore-mentioned class method ;
08053da0 T ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
or, if the nm utility is invoked as above, but this time without the use of the -C command line switch ;
08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
So far, this looks fine. The "T" in front of the definition of the class method ToolboxManager::registerToolbox
, denotes that the method resides within the Text/Code section of the file.
Similarly, if I run the nm utility (nm -C -g ./toolbox.so
) on the shared library file, it displays the following information about the same afore-mentioned class
method ;
U ToolboxManager::registerToolbox
(
std::string&,
std::string&,
std::map
<
std::string,
Factory_DSPB_Base*,
std::less
<
std::string
>,
std::allocator
<
std::pair
<
std::string const,
Factory_DSPB_Base*
>
>
>&
)
This also looks fine. The "U" in front of the definition of the class method ToolboxManager::registerToolbox
, denotes that the method is undefined in the shared library file.
However, a problem occurs when I run the binary exectable from the command line and this problem results in the following error message being displayed ;
./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
The mangled class method name which appears in this runtime message is shown below, as the first of the two lines. For comparison purposes, the mangled class method name from above (and which was generated using the the nm -g
command) is shown below as the second of the two lines ;
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
_ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE
As can be seen, the two mangled names are identical. Therefore, I cannot understand why the undefined symbol cannot be resolved at runtime.
I then re-linked the binary executable, however this time I replaced the following linker command ;
-Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt
with the this one ;
-Wl,--export-dynamic
The --export-dynamic
linker option instructs the GNU Linker to add all the symbols to the dynamic symbol table.
If then ran the binary executable again. This time it executed correctly and the call to the dlopen function did not result in an undefined symbol error. This has me utterly perplexed, as it looks as though the symbol is being exported correctly in the initial version of the binary executable. Is anyone able to see the problem here? Any assistance would be immensely appreciated.
Thanks in advance.
I have managed to solve this problem. I have found that if I remove the quotation marks from the following line ;
"ToolboxManager::registerToolbox*"
within the file ${top_srcdir}/dynamic_symbol_table.txt
and then re-link the binary executable, then it works. That is, the dlopen function will not fail anymore.
I can't help but wonder if it would have been more appropriate to ask this question on the GNU binutils mailing list than here on this web-site.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With