¿why does the executable contain the definition of symbols that are never used? (gcc)

Oct 20, 2013 at 3:21pm
I wrongfully though that when you linked several *.o the final executable would only have the necessary symbols, not all of them.
Lets say that we have

a.o:
0000000000000000 T a()
0000000000000001 T b()
0000000000000002 T c()

m.o:
0000000000000000 T m()
0000000000000001 T n()

main.o:
                 U x()
0000000000000000 T main

x.o:
                 U a()
0000000000000000 T x()
main() calls x() that calls a(), all the other functions are empty.

So now lets link all these object files and look at the executable (fat removed)
$ g++ *.o -o object.bin
$ nm -C object.bin
0000000000400580 T a()
0000000000400581 T b()
0000000000400582 T c()
0000000000400584 T m()
0000000000400585 T n()
0000000000400588 T x()
0000000000400480 T main
so it has all the functions.

However, if instead an static library is created
$ ar rcs lib.a a.o m.o x.o
$ g++ main.o lib.a -o lib.bin
$ nm -C lib.bin
0000000000400588 T a()
0000000000400589 T b()
000000000040058a T c()
0000000000400580 T x()
0000000000400480 T main
that does not have the unused functions m() and n(), but it does have b() and c().

If I understand it correctly, the undefined symbols in main.o are found in x.o so all the object file is imported. x.o also has undefined symbols, found in a.o, and again all the object file is imported.
However m.o is unneeded and thus discarded. So the dependencies are resolved at object file level instead of function level.


The thing is, we don't need the whole a.o, just the a() definition. If a rule like `only 1 function per source file' were followed, then we'll end with just the functions that we are actually using.
So ¿is there a way to make the tool behave as such?
Oct 20, 2013 at 3:43pm
AFAIK, the GNU toolchain has no direct support for function-level-linking (Microsoft has had it since 1998).

rlink seems to work out quite well. https://ribosome.helixcommunity.org/2005/devdocs/FuncLevelLinking
I tend to use a large number of small object files; so my experience with this is quite limited.

There ought to be many other similar tools floating around on the net.
Oct 20, 2013 at 5:21pm
From here (first answer):
http://stackoverflow.com/questions/6687630/c-c-gcc-ld-remove-unused-symbols

Seems to work, if I understand the problem:
gcc -Os -fdata-sections -ffunction-sections *.cpp -o object.bin -Wl,--gc-sections
nm object.bin
00000000004003c0 T main
00000000004004bd T a()
00000000004004be T x()
Oct 20, 2013 at 5:26pm
While we're on this topic I have a related question - can an executable be used as a shared library/DLL?
Oct 20, 2013 at 5:48pm
> can an executable be used as a shared library/DLL?

Platform specific; if it is supported, we would always need -fpic (or its equivalent).
http://gcc.gnu.org/ml/gcc-help/2003-07/msg00232.html
Topic archived. No new replies allowed.