Workaround for when -whole-library is not available - c++

I'm trying to compile on an environment where the -Wl,-whole-library flag is not supported (emscripten). How can I trick to force the compiler to include the exported symbols ? The solution should met as many of these properties as possible :
Could be applied on a single library (I don't want to include unused symbols from other libraries)
Could be automatically generated (for example by fetching the exported symbol table with nm?)
Would work with functions & member functions
I thought about computing a file with something like :
int x = (int)(&func_a)+(int)(&func_b)+...;
But it doesn't work with member functions, which cannot be casted to int (and can be private).
Do you have any idea ?

Ideas:
Use --whole-library flag before linking the lib you want and just
after add -no-whole-library before listing other libs so that only
the one you need To be wholly linked is and try add --export-dynamic flag using a linker that supports it.
Then dig the nm/objdump/exportmap road http://accu.org/index.php/journals/1372 to export/build link info and for using link info http://runtimecompiledcplusplus.blogspot.fr/ for using exported maps and code so that you can mimic the -Wl in your code.

Related

hide private symbols automatically

I have a C++ project with public and private header files.
To increase encapsulation and decrease symbol clashes in a larger project I would like to export only the minimal set of symbols.
Although we could manually annotate each function with visibility attributes, I'd prefer an approach that does not require changing the source code.
Given the following project structure:
LibA
include
*.h
src
*.h
*.cpp
Is there a way to automatically hide all the symbols that don't appear in include/*.h ?
Is there an elegant way of instrumenting the compiler/linker?
Could we automatically generate a version-script ?
With gcc and clang, this is as simple as building with -fvisibility=hidden. Then you only have to explicitly export the few public symbols you want exposed.
For more details, there's a gcc article on symbol visibility that you may want to read.
Could we automatically generate a version-script?
You sure could: run nm -C *.o | egrep ' [TDBW] ' to get the list of global symbols, then look in include/*.h to see which ones should be exported. This will likely be fragile: if you e.g. use macros to generate symbol names, this will probablynot work at all.
It may be worth it to generate the list once, hand-curate it, and then maintain it together with the sources by hand in the revision control system.
If the number of symbols to be exported is relatively small, compiling with -fvisibility-hidden and annotating just the public symbols is a much more robust solution.

Can a Visual Studio produced static library, be stripped of symbols?

I'll divide this questions in 3 parts:
I would like to produce a static library and strip off its symbols. (Debug info is already not included)
Similar to the strip command in linux. Can it be done?
Is there an equivalent tool in windows env, to the nm tool in linux?
When creating a static library using VS2008. Is it possible to define a script that will exclude some of the produced .obj files out of the build and out of the static lib?
Can it be dynamic? I mean I'd define a compilation mode in the script and this would result in specific object files being excluded from the build
If anything is visible that you feel should not be, try declaring it with the "static" keyword. This tells the compiler that it is accessible only to the current module.
There are cases where it would be convenient to be able to strip out all but a small number of "exported" public symbols, but it's not really feasible.
A static library is little more than a collection of .obj files. The internal dependencies haven't been resolved yet, and they won't be resolved until link time.
For example, if your .lib consists of foo.obj and bar.obj, and there's a call in foo.obj to a function defined in bar.obj, then that symbol must be available at link time, even if nothing outside of the library should be able to see it.
For that reason, you cannot strip the symbols (with the possible exception of file-scope static symbols). Even class methods that are protected or private (in the C++-sense) will exist in the symbol table, since the enforcement of the visibility is a compile-time issue, not a link-time one.
In contrast, a dynamic library is a standalone binary that has already been linked. References from foo.obj to bar.obj have already been resolved. Thus a DLL can be stripped of symbols except for the ones that must be exported (and even those can be renamed or replaced by ordinals).
If your DLL exposes a simple C API, then you're all set. But if you want to expose a C++ class, you're probably going to end up exporting all of its methods, even the protected and private ones (since inlining in the external application might result in direct calls to private methods).
No, how do you think the users of the static library would link to it without knowing where are the symbols they use defined?
Yes, try the DUMPBIN utility.
Well, yes. You can run the LIB utility with /REMOVE:foo.
That said, I think you are doing something that either is not worth doing or could be done a lot simpler than with removing library members.
I kept finding the names of certain (but not all) static functions in .obj files produced by VS2010. Interestingly, they were visible in my Release .obj files but not the Debug .obj files. I just used cygwin strings to perform the search:
$ strings myObjectFile.obj | grep myStaticFunctionName
I tracked it down to the "Whole Program Optimization = Yes" setting ("/GL"). When I switched this to "No" the function names no longer appear.
Update: As a followup test I opened the "cleansed" myObjectFile.obj in vim and I can still find them (with either :set encoding=utf-8 or :set encoding=latin1). I'm not sure why strings was missing the matches. Oh well.

gcc's fvisibility at compile time or link time

I am trying to limit the ABI of a shared library using the gcc's fvisibility feature. However I am confused what is the correct way to do it.
My makefile organizes the build process in two stages. At the first step all .cpp files are built to object files using some gcc options. Then all the object files are linked together using another set of gcc and ld options. From what I have read fvisibility is relevant to the second step. However this contradicts with the results I observer. If I add fvisibility=hidden to the compile time options the result is as expected, nm -D reporting a much smaller set of exported symbols. On the contrary if I add it to the link time options it does not seem to affect the build.
While looking for an explanation I have compared the object files produced with and without fvisibility. The difference seems to be in the addresses of the symbols inside the object file. However I am not aware how that difference in addresses carries the message to the linker so that it is able to hide the symbols in one of the cases and expose them in the other.
Could anyone please explain to me that. Thank you for your time.
Compile time, as the visibility is placed in the object (.o) files, and then used by the linker when creating the complete executable/shared object. When using it at link time, but not compile time, it will have no effect, as the visibility in the object files is still default. There's also no need to use it at link time at all I've found.
In the case of how the visibility is stored, the different symbols are probably in different segments, and they get their visibility from the options of the segment.
You may find http://gcc.gnu.org/wiki/Visibility to be helpful

Is there a .def file equivalent on Linux for controlling exported function names in a shared library?

I am building a shared library on Ubuntu 9.10. I want to export only a subset of my functions from the library. On the Windows platform, this would be done using a module definition (.def) file which would contain a list of the external and internal names of the functions exported from the library.
I have the following questions:
How can I restrict the exported functions of a shared library to those I want (i.e. a .def file equivalent)
Using .def files as an example, you can give a function an external name that is different from its internal name (useful for prevent name collisions and also redecorating mangled names etc)
On windows I can use the EXPORT command (IIRC) to check the list of exported functions and addresses, what is the equivalent way to do this on Linux?
The most common way to only make certain symbols visible in a shared object on linux is to pass the -fvisibility=hidden to gcc and then decorate the symbols that you want to be visible with __attribute__((visibility("default"))).
If your looking for an export file like solution you might want to look at the linker option --retain-symbols-file=FILENAME which may do what you are looking for.
I don't know an easy way of exporting a function with a different name from its function name, but it is probably possible with an elf editor. Edit: I think you can use a linker script (have a look at the man page for ld) to assign values to symbols in the link step, hence giving an alternative name to a given function. Note, I haven't ever actually tried this.
To view the visible symbols in a shared object you can use the readelf command. readelf -Ds if I remember correctly.
How can I restrict the exported functions of a shared library to those I want (i.e. a .def file equivalent)
Perhaps you're looking for GNU Export Maps or Symbol Versioning
g++ -shared spaceship.cpp -o libspaceship.so.1
-Wl,-soname=libspaceship.so.1 -Wl,
--version-script=spaceship.expmap
gcc also supports the VC syntax of __declspec(dllexport). See this.
Another option is to use the strip command with this way:
strip --keep-symbol=symbol_to_export1 --keep-symbol=symbol_to_export2 ... \
libtotrip.so -o libout.so

C++ shared library shows internal symbols

I have built a shared library (.dll, .so) with VC++2008 and GCC.
The problem is that inside both libs it shows the names of private symbols (classes, functions) and they weren't exported.
I don't want my app to display the name of classes/functions that weren't exported.
Is any way i can do that?
In GCC i did:
Compiled with -fvisibility=hidden and then made public with attribute ((visibility("default")))
In VC++:
__declspec(dllexport)
Thanks!
For GNU tool chains you can use th strip command to remove symbols from object files. It takes various command options to control its behavior. It may do what you want.
You can create a header file to obfuscate the internal function and method names you want to be hidden. Ie something like below (need some include guard too)
#define someFunctionName1 sJkahe28273jwknd
#define someFunctionName2 lSKlajdwe98
#define someMethodName1 ksdKLJLKJl22fss
#define someMethodName2 lsk89hHHuhu7g
...and include this in the header files where the real definitions live.
The private keyword when used for access specification only
effectively works at compile time and is intended as an aid to programmers, not a security feature - as you have found out the "privacy" is implemented
using lexical means .
It's easy to see that this must be so - if you implement two private functions with dependencies between each other in two separate .cpp files, the linker has to find the private names in the resulting object (or library) files.
Bottom line - C++ has no code security features - if you give someone the object code of your program, they will always be able to examine it.