This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]