svn commit: r255931 - head/contrib/binutils/bfd

Dimitry Andric dim at FreeBSD.org
Mon Sep 30 21:00:12 UTC 2013


On Sep 29, 2013, at 01:03, Dimitry Andric <dim at freebsd.org> wrote:
> Author: dim
> Date: Sat Sep 28 23:03:40 2013
> New Revision: 255931
> URL: http://svnweb.freebsd.org/changeset/base/255931
> 
> Log:
>  Fix a bug in ld, where indirect symbols are not handled properly during
>  linking of a shared library, leading to corrupt indexes in the dynamic
>  symbol table.  This should fix the multimedia/ffmpegthumbnailer port.

The reason for this commit is an unfortunate interaction between our
base ld (which is at 2.17.50, quite ancient), and ports ld (2.23.2).

The latter version can put versioned symbols into an .so file in a way
that is not handled by the former version, leading to corrupt symbol
table entries.

Here is an example, derived from the original problem Steve Wills
reported.  Suppose we are building a libavcodec.so, which uses versioned
symbols, and it assigns those versions to *all* its symbols, using the
following version script:

$ cat libavcodec.ver
LIBAVCODEC_52 {
        global: *;
};

Next we link some empty object file (the contents do not matter) into
libavcodec.so, using the version script, with the base ld:

$ touch empty.c
$ cc empty.c -o libavcodec.so -shared -s -Wl,--version-script,libavcodec.ver

The resulting .so file has several NOTYPE GLOBAL symbols (_end, _edata
and __bss_start), which are marked as ABS (absolute):

$ readelf -a libavcodec.so | grep -A8 "Symbol table '\.dynsym'"
Symbol table '.dynsym' contains 9 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000   413 FUNC    WEAK   DEFAULT  UND __cxa_finalize at FBSD_1.0 (3)
     2: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
     3: 00001510     0 NOTYPE  GLOBAL DEFAULT  ABS _end@@LIBAVCODEC_52
     4: 00001510     0 NOTYPE  GLOBAL DEFAULT  ABS _edata@@LIBAVCODEC_52
     5: 00000000     0 OBJECT  GLOBAL DEFAULT  ABS LIBAVCODEC_52
     6: 00001510     0 NOTYPE  GLOBAL DEFAULT  ABS __bss_start@@LIBAVCODEC_52

But if you link the .so with the ports ld (by using the cc -B option),
the output is slightly different:

$ cc -B/usr/local/bin empty.c -o libavcodec.so -shared -s -Wl,--version-script=libavcodec.ver

The resulting .so file again has several NOTYPE GLOBAL symbols, but this
time they point to the .data section (Ndx=21 in this case):

$ readelf -a libavcodec.so | grep -A8 "Symbol table '\.dynsym'"
Symbol table '.dynsym' contains 9 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
     2: 00000000     0 FUNC    WEAK   DEFAULT  UND __cxa_finalize at FBSD_1.0 (3)
     3: 00001510     0 NOTYPE  GLOBAL DEFAULT   21 _edata@@LIBAVCODEC_52
     4: 00001510     0 NOTYPE  GLOBAL DEFAULT   21 _end@@LIBAVCODEC_52
     5: 00000000     0 OBJECT  GLOBAL DEFAULT  ABS LIBAVCODEC_52
     6: 00001510     0 NOTYPE  GLOBAL DEFAULT   21 __bss_start@@LIBAVCODEC_52

If you now attempt to link any other .so file, using the libavcodec.so
produced by ports ld as a dependency, with the _base_ ld, it will not
handle those symbols correctly, and corrupt them:

$ cc empty.c -o libffmpegthumbnailer.so -shared -s libavcodec.so
$ readelf -a libffmpegthumbnailer.so | grep -A8 "Symbol table '\.dynsym'"
Symbol table '.dynsym' contains 8 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND
     1: 00000000   413 FUNC    WEAK   DEFAULT  UND __cxa_finalize at FBSD_1.0 (2)
     2: 00000000     0 NOTYPE  WEAK   DEFAULT  UND _Jv_RegisterClasses
     3: a5a5a5a5 0xa5a5a5a5 COMMON  <OS specific>: 10 INTERNAL [<other>: a4]  bad section index[42405] <corrupt>
     4: a5a5a5a5 0xa5a5a5a5 COMMON  <OS specific>: 10 INTERNAL [<other>: a4]  bad section index[42405] <corrupt>
     5: a5a5a5a5 0xa5a5a5a5 COMMON  <OS specific>: 10 INTERNAL [<other>: a4]  bad section index[42405] <corrupt>
     6: 00000260     0 FUNC    GLOBAL DEFAULT    9 _init

Any attempt to link with the resulting libffmpegthumbnailer.so will
fail.  (The a5a5a5a5 number is actually an uninitialized value.)

The r255931 commit fixes this by making ld properly handle these
so-called 'indirect' symbols, similar to what upstream ld has already
implemented.

-Dimitry

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 203 bytes
Desc: Message signed with OpenPGP using GPGMail
URL: <http://lists.freebsd.org/pipermail/svn-src-all/attachments/20130930/26ab5d40/attachment.sig>


More information about the svn-src-all mailing list