This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[patch] stop objcopy breaking group sections
- From: Andrew Stubbs <ams at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Wed, 24 Sep 2008 16:12:04 +0100
- Subject: [patch] stop objcopy breaking group sections
Hi,
objcopy (and strip -g) has a bug that breaks group sections. I've tested
it using arm-none-eabi, but the problem almost certainly affects all
targets.
To reproduce:
---test.cxx-------
class X
{
public:
int nokey() {return 0;}
};
int b(X*);
void t1()
{
class X x;
b(&x);
x.nokey();
}
-----------------
$ arm-none-eabi-g++ -O0 -c test.cxx
$ arm-none-eabi-readelf -S -g -s test.o
...
[ 1] .group GROUP 00000000 000034 000010 04
17 15 4
...
15: 00000000 36 FUNC WEAK DEFAULT 6 _ZN1X5nokeyEv
...
COMDAT group section [ 1] `.group' [_ZN1X5nokeyEv] contains 3 sections:
$ arm-none-eabi-objcopy test.o new.o
$ arm-none-eabi-readelf -S -g -s new.o
...
[ 1] _ZN1X5nokeyEv GROUP 00000000 000034 000010 04
17 14 4
...
14: 00000000 0 SECTION LOCAL DEFAULT 1
...
COMDAT group section [ 1] `_ZN1X5nokeyEv' [_ZN1X5nokeyEv] contains 3
sections:
In each case I have shown the symbol indicated by the sh_info field. As
you can see, it changes from 15 to 14, but the relevant symbol isn't in
location 14 - it's still at 15. The section name has also been changed,
but this is harmless, if undisirable. Unfortunately, the behaviour of
readelf when sh_info doesn't make sense seems to somehow find the right
value by chance, but the linker doesn't do the same. The new binary will
no longer link correctly.
On closer investigation it turns out that the number 14 is "random" -
that is, the algorithm gets it from totally the wrong place, although it
has a predictable value.
In fact, it seems that code has been written to write sh_info, in the
case of the assembler, read it, in the case of the linker, but the code
to copy it is totally missing.
The attached patch should rectify this situation. I did also attempt to
prevent it modifying the section name, but the linker is incapable of
linking binaries where multiple sections have the same name (it only
links in one of them), so I've given up on that.
OK?
Andrew Stubbs
2008-09-24 Andrew Stubbs <ams@codesourcery.com>
* elf.c (elf_fake_sections): Find the signature symbol for
SHT_GROUP sections when doing objcopy/strip.
Index: bfd/elf.c
===================================================================
--- bfd/elf.c.orig 2008-08-08 09:00:14.000000000 +0100
+++ bfd/elf.c 2008-09-24 15:43:20.000000000 +0100
@@ -2622,6 +2622,25 @@ elf_fake_sections (bfd *abfd, asection *
case SHT_GROUP:
this_hdr->sh_entsize = GRP_ENTRY_SIZE;
+
+ /* Find the group signature symbol from the name. This only applies if
+ we don't already have a valid symbol and there are symbols available:
+ gas - symbol provided already.
+ ld - name given, no symbols available, no symbol needed.
+ objcopy/strip - name given, symbol required.
+ This relies on bfd_section_from_shdr naming the section using the
+ group signature. */
+ if (elf_group_id (asect) == NULL && bfd_get_outsymbols (abfd) != NULL)
+ {
+ unsigned int i;
+ for (i = 0; i < bfd_get_symcount (abfd); i++)
+ if (strcmp (bfd_section_name (abfd, asect),
+ bfd_asymbol_name (bfd_get_outsymbols (abfd) [i])) == 0)
+ {
+ elf_group_id (asect) = bfd_get_outsymbols (abfd) [i];
+ break;
+ }
+ }
break;
case SHT_GNU_HASH: