This is the mail archive of the
binutils@sources.redhat.com
mailing list for the binutils project.
ld -r frustration
- From: Alan Modra <amodra at bigpond dot net dot au>
- To: binutils at sources dot redhat dot com
- Date: Wed, 28 Jul 2004 00:41:03 +0930
- Subject: ld -r frustration
Every so often I get a bug report about TOC overflow when linking on
PowerPC64 Linux. With the automatic multiple TOC support in GNU ld,
this ought not happen very often; You need a single object file to
exceed the 64k TOC limit. However, people use "ld -r" to combine
object files, sometimes very many object files. So they end up with
a TOC section that's too big. "Too bad", I say. "Don't use ld -r".
That's not the ideal solution, especially considering that tools
like libtool use "ld -r" to work around command line limits when
linking huge numbers of object files. What we really need is a
"ld -r" that doesn't do any merging of sections, or a final link
stage that can undo the effects of "ld -r". The latter would need
quite a bit of work, and probably not be very robust. I'm leaning
towards the idea of making "ld -r" behave like "ar cr" on PowerPC64.
The only trick needed is that when using the resulting archive in a
final link we want the linker to behave as if --whole-archive were in
effect. ie. the archive needs to be tagged specially in some way that
the linker can recognise. I could do that quite easily by twiddling
the magic string at the start of an archive. What's more, you could
handle the whole business of making "ld -r" invoke "ar cr" and twiddle
the magic string in a shell script.
Comments? Better ideas?
The binutils hack will look something like the following (untested!)
Index: bfd/archive.c
===================================================================
RCS file: /cvs/src/src/bfd/archive.c,v
retrieving revision 1.31
diff -u -p -r1.31 archive.c
--- bfd/archive.c 19 May 2004 14:46:59 -0000 1.31
+++ bfd/archive.c 27 Jul 2004 15:09:22 -0000
@@ -581,6 +581,11 @@ bfd_generic_archive_p (bfd *abfd)
return NULL;
}
+ /* Recognise a magic string starting with '#' too. These are
+ archives that ld will link as if --whole-archive was given. */
+ if (armag[0] == '#')
+ armag[0] = '!';
+
#ifdef GNU960
if (strncmp (armag, BFD_GNU960_ARMAG (abfd), SARMAG) != 0)
return 0;
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.160
diff -u -p -r1.160 ldlang.c
--- ld/ldlang.c 23 Jul 2004 16:32:53 -0000 1.160
+++ ld/ldlang.c 27 Jul 2004 15:09:24 -0000
@@ -1368,6 +1368,14 @@ load_symbols (lang_input_statement_type
break;
case bfd_archive:
+ if (!entry->whole_archive)
+ {
+ char magic;
+ if (bfd_seek (entry->the_bfd, 0, SEEK_SET) == 0
+ && bfd_bread (&magic, 1, entry->the_bfd) == 1
+ && magic == '#')
+ entry->whole_archive = 1;
+ }
if (entry->whole_archive)
{
bfd *member = NULL;
--
Alan Modra
IBM OzLabs - Linux Technology Centre