I have created a Win32-DLL using MSVC 2010 that contains unwanted exported C++ symbols. I'm using a module definition file (.def) and __stdcall convention for specific functions that I want to export. However, due to the fact that I am also using Boost Serialization there is a ton of exported C++ symbols from Boost. These symbols are exported by Boost due to this fact (found here):
I am using boost::serialization from 1.44.0. One thing that I noticed is that linking statically to the serialization libs will add several hundred exports in the final exe file that I get. Using
dumpbin /exports my_program.exeThese functions are not explicity called from the library. But they ARE called as part of the serialization process. Its just that MSVC doesn't see them. So when you compile for release, The MSVC Linker strips them out and the program won't work anymore. In order to work around this, these functions are explicitly exported. This prevents MSVC from stripping them out. For more information see force_include.hpp
Exported symbols (excerpt):
class boost::archive::detail::extra_detail::map<class boost::archive::binary_oarchive> & >boost::serialization::singleton<class boost::archive::detail::extra_detail::map<class boost::archive::binary_oarchive> >::get_instance(void)'::`2'::`local static guard'{2}'
You can recreate the situation by creating a DLL project and include Boost (link against libboost_serialization-vc100-mt-gd-1_55.lib):
#include <boost/archive/binary_oarchive.hpp>
#include <fstream>
extern "C" int __stdcall test();
int __stdcall test() {
std::fstream stream;
boost::archive::binary_oarchive o(stream, boost::archive::no_header);
return 1;
}
I tested the GNU utility strip from binutils. However, it seems it always removes all symbols. E.g. using this command
strip --strip-symbol=test DllBoostTest.dll -o test.dll
This simple test does not work. It should remove only the test symbol. Unfortunately, it also removes all symbols. Also using wildcards and -N does not work as it removes all exports, too.
So is there a way to remove all unwanted boost C++ symbols? Say, remove all symbols with "boost" text in it?
If you need more information, I'm happy to provide it.
Note: This is not about debugging or PDB files!
This is quite hard to fix in a clean way. A true fix would be to take the sting out the boost hack to force these symbols to be included. Which would require removing the __declspec(dllexport) attribute and either use the /OPT:NOREF linker option to suppress the optimization or use /INCLUDE (or #pragma comment) to ensure that the symbols are included. This however requires rebuilding the boost library and is yucky maintenance due to the unpredictability of the mangled names. So you probably don't like that option, the Boost team clearly didn't.
I don't think trying to hack strip is going to get you anywhere, it is important that the linker still sees the symbols so it doesn't optimize them away. You could only do this after building the DLL, that requires rewriting the export tables in the file. This is technically possible but not easy to do.
One possibility is to prevent these names from being visible. The DEF file gives you that option, you can use the NONAME attribute to prevent the name from being visible and the PRIVATE attribute to prevent the name from being visible in the import library. Make it look like this:
EXPORTS
??_B?1??get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ@51 @1 NONAME PRIVATE
??_B?1??get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ@51 @2 NONAME PRIVATE
?get_const_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SAABV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @3 NONAME PRIVATE
?get_const_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SAABV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @4 NONAME PRIVATE
?get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @5 NONAME PRIVATE
?get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @6 NONAME PRIVATE
?get_mutable_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@XZ @7 NONAME PRIVATE
?get_mutable_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ @8 NONAME PRIVATE
?instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@0AAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@3@A @9 NONAME PRIVATE
?instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@0AAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@A @10 NONAME PRIVATE
?is_destroyed@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@SA_NXZ @11 NONAME PRIVATE
?is_destroyed@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@SA_NXZ @12 NONAME PRIVATE
?t@?1??get_instance@?$singleton@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@serialization@boost@@CAAAV?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@4@XZ@4V?$singleton_wrapper@V?$map@Vbinary_oarchive@archive@boost@@@extra_detail@detail@archive@boost@@@734@A @13 NONAME PRIVATE
?t@?1??get_instance@?$singleton@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@serialization@boost@@CAAAV?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@XZ@4V?$singleton_wrapper@V?$multiset@PBVextended_type_info@serialization@boost@@Ukey_compare@detail@23@V?$allocator@PBVextended_type_info@serialization@boost@@@std@@@std@@@detail@34@A @14 NONAME PRIVATE
_test@0 = _test@0
You will get LNK4197 warnings because the linker sees two export requests, one from the __declspec(dllexport) and another from the DEF file. These warnings are benign and you can ignore them. Note that you may have to tweak these names, I tested this with VS2012 and Boost version 1.53
After deleting the PDB file (don't forget), the exports look like this:
ordinal hint RVA name
15 0 0001582F _test@0
1 0004DE94 [NONAME]
2 0004DEB8 [NONAME]
3 0001524E [NONAME]
4 000153A2 [NONAME]
5 00015AA5 [NONAME]
6 00015460 [NONAME]
7 000154E7 [NONAME]
8 00016199 [NONAME]
9 0004DE7C [NONAME]
10 0004DEA0 [NONAME]
11 00015AFF [NONAME]
12 00015B9F [NONAME]
13 0004DE84 [NONAME]
14 0004DEA8 [NONAME]
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