This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Re: Fix uninitialized data in .dynsym
On Fri, Jul 06, 2007 at 11:07:40PM +0000, Joseph S. Myers wrote:
> 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;
>
I don't think it is right. When you do
ld -shared -o b.so --defsym foo=0 a.so --version-script a.ver -E
shouldn't foo be dynamic?
H.J.