Problem getting GNU linker (ld) to export character

I use some GNU tools, i.e. GNU C ++ compiler (g ++) and GNU Linker (ld) to create a shared library file (.so), as well as an executable file.

The binary executable uses the dlopen function to dynamically load the shared library file at run time. In addition to this, the shared library file needs to call a specific class method (called ToolboxManager::registerToolbox ), which is defined in the binary executable. This is achieved by forcing the class method executable to export, which, in turn, is executed during the connection, linking the binary executable file with the following command line parameters:

 -Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

where the file ${top_srcdir}/dynamic_symbol_table.txt contains the following contents;

 { extern "C++" { "ToolboxManager::registerToolbox*"; }; }; 

Note the use of an asterisk (*) in the file to force the linker to export all characters starting with ToolboxManager::registerToolbox .

When I run the GNU nm utility ( nm -C -g ./a.out ) in the resulting binary executable, it displays the following information about the above 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 nm is invoked as described above, but this time without using the -C command line switch;

 08053da0 T _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

So far it looks good. A "T" before defining a method of the ToolboxManager::registerToolbox class means that this method is in the "Text / Code" section of the file.

Similarly, if I run the nm utility ( nm -C -g ./toolbox.so ) in a shared library file, it displays the following information about the same method class listed above;

 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* > > >& ) 

It also looks great. A "U" before defining a method of the ToolboxManager::registerToolbox class means that the method is undefined in the shared library file.

However, there is a problem when I run the binary from the command line, and this problem results in the following error message:

 ./toolbox.so: undefined symbol: _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

The method name of the modified class that appears in this runtime message is shown below as the first of two lines. For comparison, the name of the method with the modified class at the top (and which was generated using the nm -g command) is shown below as the second of two lines;

 _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE _ZN14ToolboxManager15registerToolboxERSsS0_RSt3mapISsP17Factory_DSPB_BaseSt4lessISsESaISt4pairIKSsS3_EEE 

As you can see, the two distorted names are identical. Therefore, I cannot understand why the undefined character cannot be resolved at runtime.

Then I re-linked the binary executable, however this time I replaced the following linker command:

 -Wl,--dynamic-list=${top_srcdir}/dynamic_symbol_table.txt 

with this,

 -Wl,--export-dynamic 

The linker option --export-dynamic tells GNU Linker to add all characters to the dynamic symbol table.

If then run the executable again. This time it performed correctly, and the call to the dlopen function did not result in an undefined character error. This completely puzzles me, since it seems that the character is exported correctly in the original version of the binary executable. Can anyone see the problem here? Any help would be greatly appreciated.

Thanks in advance.

+7
source share
1 answer

I managed to solve this problem. I found that if I remove quotes from the next line,

 "ToolboxManager::registerToolbox*" 

in the file ${top_srcdir}/dynamic_symbol_table.txt , and then re-link the binary executable file, then it works. That is, the dlopen function will no longer fail.

I cannot help but wonder if it would be more appropriate to ask this question on the GNU binutils mailing list than here on this website.

+3
source

All Articles