This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Fix uninitialized data in .dynsym
- From: "Joseph S. Myers" <joseph at codesourcery dot com>
- To: binutils at sourceware dot org
- Date: Fri, 6 Jul 2007 23:07:40 +0000 (UTC)
- Subject: Fix uninitialized data in .dynsym
This patch fixes a problem where .dynsym ends up containing
uninitialized data (commonly but not always 0s).
ld allocates an entry in .dynsym then fails to fill it in.
elf_link_output_extsym decides not to output the symbol, previously
allocated a dynindx value, in the case:
case bfd_link_hash_indirect:
/* These symbols are created by symbol versioning. They point
to the decorated version of the name. For example, if the
symbol foo@@GNU_1.2 is the default, which should be used when
foo is used with no version, then we add an indirect symbol
foo which points to foo@@GNU_1.2. We ignore these symbols,
since the indirected symbol is already in the hash table. */
return TRUE;
I think this means there is no need for the symbol to be output, and
so it need not be allocated a dynindx value.
For the following testcase, "readelf -s" outputs (on
i686-pc-linux-gnu) the following output for .dynsym before the patch
(note the stray symbol 2):
Symbol table '.dynsym' contains 6 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 00001214 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
2: 00000000 0 NOTYPE LOCAL DEFAULT UND
3: 00001214 0 NOTYPE GLOBAL DEFAULT ABS _edata
4: 00001214 0 NOTYPE GLOBAL DEFAULT ABS _end
5: 00000000 0 OBJECT GLOBAL DEFAULT ABS FOO
and the following after:
Symbol table '.dynsym' contains 5 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 00000000 0 NOTYPE LOCAL DEFAULT UND
1: 000011fc 0 NOTYPE GLOBAL DEFAULT ABS __bss_start
2: 000011fc 0 NOTYPE GLOBAL DEFAULT ABS _edata
3: 000011fc 0 NOTYPE GLOBAL DEFAULT ABS _end
4: 00000000 0 OBJECT GLOBAL DEFAULT ABS FOO
A key part of the test appears to be that a symbol gets assigned in a
linker script or on the linker command line; the original case where I
investigated it involved __data_start on ARM being assigned versions
by version scripts mentioning __*.
I haven't managed to produce a test in a sensible form for inclusion
in the ld testsuite. The trouble is that the readelf output above
depends on details of symbols allocated by the default linker script
for a particular target - and if you try to avoid that by providing a
special linker script just for the test, such a script needs to be
rather complicated to be able to build shared libraries. The most
reliable indication of whether the issue is fixed is probably not
readelf output anyway, but the lack of an uninitialized memory report
from valgrind. Here is the test as a series of shell commands.
cat > a.ver <<EOF
FOO { foo; };
EOF
cat >a.c <<EOF
void foo(void) {}
EOF
gcc -c a.c
ld -shared -o a.so a.o --version-script a.ver
ld -shared -o b.so --defsym foo=0 a.so --version-script a.ver -E
readelf -s b.so
Comments? OK to commit?
2007-07-06 Joseph Myers <joseph@codesourcery.com>
* elflink.c (bfd_elf_link_record_dynamic_symbol): Do not set
dynindx for indirect symbols.
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.268
diff -u -p -r1.268 elflink.c
--- bfd/elflink.c 6 Jul 2007 02:29:10 -0000 1.268
+++ bfd/elflink.c 6 Jul 2007 22:53:01 -0000
@@ -398,6 +398,9 @@ bfd_elf_link_record_dynamic_symbol (stru
break;
}
+ if (h->root.type == bfd_link_hash_indirect)
+ return TRUE;
+
h->dynindx = elf_hash_table (info)->dynsymcount;
++elf_hash_table (info)->dynsymcount;
--
Joseph S. Myers
joseph@codesourcery.com