This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
ld with --retain-symbols-file
- From: Steve Peltz <sep at shout dot net>
- To: binutils at sourceware dot org
- Date: Thu, 31 Jul 2008 05:17:45 -0500
- Subject: ld with --retain-symbols-file
Apologies if this has been discussed before, I was unable to find
anything about it.
The --retain-symbols-file option to ld seems to me to be less than
useful, as it "retains symbols needed for relocation".
If I have two sets of .o files, and I want to partial-link each set,
resolving all symbols and only keeping the ones I'm going to
reference, it seems I generally can not do that if any of those
symbols are referenced within their set (or even just within the same
file).
Using Apple's linker, if I use the equivalent option -
exported_symbols_list, it does what I would expect - any symbol that
it needs to retain it changes into a local symbol (other than
undefined symbols, of course). With GNU ld, it just leaves a lot of
symbols alone, so when I then try to link the two partially-linked
files into another program, I get duplicate symbols.
Seems to me the behavior of --retain-symbols-file should work that
way, as well as resolve any common symbols that aren't mentioned in
the file the same way -d would do it (but any common symbol that IS
referenced in the symbols file should simply remain a common symbol,
unless -d is also used). The result would be that the ONLY global
symbols retained in the file are the ones listed. This one isn't that
important to me, I'm fine with just using -d, but it would make it
work the way you'd expect.
Example, files a.c and x.c both define a(), b() and c(), and
initialized variables x and y (in a.c), uninitialized (common)
variables x and y (in x.c); x and y are referenced by a() and b(), a()
makes a forward reference to c(), c() makes a backwards reference to
b().
File b.c contains routine_a() which references a(); file y.c contains
routine_b(), which references b().
File z.c has a main routine which references routine_a() and
routine_b().
File symbols contains "routine_a" and "routine_b" lines.
After compiling all the .c files:
ld -r -o ab.o --retain-symbols-file symbols a.o b.o
ld -r -o xy.o --retain-symbols-file symbols x.o y.o
cc -o z z.o ab.o xy.o
ab.o contains symbols for a(), c(), x, and y.
xy.o contains symbols for b(), c(), x, and y.
I get duplicate symbols for c() when I try to link the executable,
and x and y are the same between ab.o and xy.o (since one is a common
reference). If I use -d when linking xy.o, then I get duplicate
symbols for x and y instead.
ab.o doesn't contain b(), since it wasn't referenced by routine_a(),
and the backwards reference from c() apparently didn't go through the
symbol. ab.o and xy.o contain c() only because of the forward
reference from a() to c(), which apparently does go through the symbol.
Is there any other way I can selectively remove symbols from a .o file
the way I want? There also should be a way to have ld remove all
local symbols from the file, just leave simple relocation entries
rather than symbol references, but again, that's much less important.
It just seems to me that there's no reason it can't simply change
those symbols to be local rather than global, or eliminate them
entirely. Am I nuts for thinking it should be this way?