Bug 12548 - anonymous version scripts no longer working with binutils 2.21
Summary: anonymous version scripts no longer working with binutils 2.21
Status: NEW
Alias: None
Product: binutils
Classification: Unclassified
Component: ld (show other bugs)
Version: 2.22
: P2 normal
Target Milestone: ---
Assignee: unassigned
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2011-03-07 12:30 UTC by Pierre Ossman
Modified: 2015-12-22 14:35 UTC (History)
7 users (show)

See Also:
Host:
Target: *-*-solaris2*
Build:
Last reconfirmed:


Attachments
elfdump liblib.so (4.22 KB, text/plain)
2012-10-10 19:40 UTC, Igor Pashev
Details
proposed patch (289 bytes, patch)
2012-11-13 21:11 UTC, Igor Pashev
Details | Diff
Solaris specific version of previous patch (441 bytes, patch)
2015-12-22 12:39 UTC, Nick Clifton
Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Pierre Ossman 2011-03-07 12:30:07 UTC
I upgraded our build system from binutils 2.20 and gcc 4.4.3 to binutils 2.21 and gcc 4.5.2. This unfortunately broke support for anonymous version scripts. Example from libjpeg-turbo:

sparc-sun-solaris2.10-gcc -shared  .libs/jcapimin.o .libs/jcapistd.o .libs/jccoefct.o .libs/jccolor.o .libs/jcdctmgr.o .libs/jchuff.o .libs/jcinit.o .libs/jcmainct.o .libs/jcmarker.o .libs/jcmaster.o .libs/jcomapi.o .libs/jcparam.o .libs/jcphuff.o .libs/jcprepct.o .libs/jcsample.o .libs/jctrans.o .libs/jdapimin.o .libs/jdapistd.o .libs/jdatadst.o .libs/jdatasrc.o .libs/jdcoefct.o .libs/jdcolor.o .libs/jddctmgr.o .libs/jdhuff.o .libs/jdinput.o .libs/jdmainct.o .libs/jdmarker.o .libs/jdmaster.o .libs/jdmerge.o .libs/jdphuff.o .libs/jdpostct.o .libs/jdsample.o .libs/jdtrans.o .libs/jerror.o .libs/jfdctflt.o .libs/jfdctfst.o .libs/jfdctint.o .libs/jidctflt.o .libs/jidctfst.o .libs/jidctint.o .libs/jidctred.o .libs/jquant1.o .libs/jquant2.o .libs/jutils.o .libs/jmemmgr.o .libs/jmemnobs.o .libs/jaricom.o .libs/jcarith.o .libs/jdarith.o .libs/jsimd_none.o .libs/turbojpegl.o  -lc  -Wl,--version-script -Wl,./turbojpeg-mapfile -Wl,-soname -Wl,libturbojpeg.so -o .libs/libturbojpeg.so
/usr/lib/gcc/sparc-sun-solaris2.10/4.5.2/../../../../sparc-sun-solaris2.10/bin/ld: anonymous version tag cannot be combined with other version tags

Contents of turbojpeg-mapfile:

{
	global:
		tjInitCompress;
		tjCompress;
		TJBUFSIZE;
		tjInitDecompress;
		tjDecompressHeader;
		tjDecompressHeader2;
		tjDecompress;
		tjDestroy;
		tjGetErrorStr;
	local:
		*;
};

The problem is specific to the Solaris/sparc backend. I have the same binutils/gcc pair built and targeting i686, x86_64, win32 and win64 and I do not get the problem there.

After some digging, I found that the problem is in ld/emultempl/solaris2.em, which is part of the new Solaris 2 ABI stuff. It tries to add a new version section for a bunch of symbols, which of course won't work when there is already an anonymous section from the command line.

I'm not sure how to proceed here. I have to assume this version section is being added for a reason, so I can't just remove it. Perhaps the entries need to be merged with the existing section?
Comment 1 Lionel Elie Mamane 2011-11-12 23:49:50 UTC
(In reply to comment #0)
> I upgraded our build system from binutils 2.20 and gcc 4.4.3 to binutils 2.21
> and gcc 4.5.2. This unfortunately broke support for anonymous version scripts.
> /usr/lib/gcc/sparc-sun-solaris2.10/4.5.2/../../../../sparc-sun-solaris2.10/bin/ld:
> anonymous version tag cannot be combined with other version tags

> The problem is specific to the Solaris/sparc backend.

> After some digging, I found that the problem is in ld/emultempl/solaris2.em,
> which is part of the new Solaris 2 ABI stuff. It tries to add a new version
> section for a bunch of symbols, which of course won't work when there is
> already an anonymous section from the command line.

> I'm not sure how to proceed here. I have to assume this version section is
> being added for a reason, so I can't just remove it. Perhaps the entries need
> to be merged with the existing section?

Or more prosaically, allow an anonymous version tag to cohabit with a named version tag. I just requested that for different reasons in bug 13406.
Comment 2 Alasdair Lumsden 2011-12-23 15:19:14 UTC
Hi There,

We're encountering this too. I take it this hasn't been fixed in 2.22?

We had to revert to 2.20 and can't move forward until this is fixed.

Regards,

Alasdair
Comment 3 Igor Pashev 2012-02-25 07:34:55 UTC
What about assigning [on the fly] some tag instead to those "anonymous" tags?

Say "__solaris_anon" or whatsoever. Or maybe "Base". dpkg-gensymbols list
anonymous tags as @Base. In any case if this will be fixed in other way, we can
use LD_NOVERSION for transition.
Comment 4 Igor Pashev 2012-10-10 12:38:05 UTC
Could this be caused by symbol "_lib_version" which is compiled in in every binary from values-X[].o ? "_lib_version" has version tag associated with it in libc.
Comment 5 Igor Pashev 2012-10-10 13:14:30 UTC
(In reply to comment #4)
> Could this be caused by symbol "_lib_version" which is compiled in in every
> binary from values-X[].o ? "_lib_version" has version tag associated with it in
> libc.

Oh, no. It is ld/emultempl/solaris2.em.
Comment 6 Igor Pashev 2012-10-10 13:58:45 UTC
(In reply to comment #5)
> (In reply to comment #4)
> > Could this be caused by symbol "_lib_version" which is compiled in in every
> > binary from values-X[].o ? "_lib_version" has version tag associated with it in
> > libc.
> 
> Oh, no. It is ld/emultempl/solaris2.em.

Some more info:

http://sourceware.org/ml/binutils/2010-02/msg00457.html
http://docs.oracle.com/cd/E19082-01/819-0690/chapter2-88783/index.html
Comment 7 Igor Pashev 2012-10-10 14:58:35 UTC
(In reply to comment #6)
> (In reply to comment #5)
> > (In reply to comment #4)
> > > Could this be caused by symbol "_lib_version" which is compiled in in every
> > > binary from values-X[].o ? "_lib_version" has version tag associated with it in
> > > libc.
> > 
> > Oh, no. It is ld/emultempl/solaris2.em.
> 
> Some more info:
> 
> http://sourceware.org/ml/binutils/2010-02/msg00457.html
> http://docs.oracle.com/cd/E19082-01/819-0690/chapter2-88783/index.html

Here is a nice question:

http://sourceware.org/ml/binutils/2010-02/msg00475.html

"What breaks if you omit these symbols?"

AFAIK Nexanta Core Platform <= 3 was using GNU ld by default,
and, I guess, without those symbols.
Comment 8 Igor Pashev 2012-10-10 19:38:50 UTC
BTW, Solaris linker is completely happy with anonymous tags.


# cat lib.c 
int hello(void)
{
    return -1;
}


# cat map 
{
    global:
        hello;
    local:
        *;
};

# gcc -shared lib.c -o liblib.so -Wl,-M,map


// See attached elfdump
Comment 9 Igor Pashev 2012-10-10 19:40:22 UTC
Created attachment 6681 [details]
elfdump liblib.so
Comment 10 Igor Pashev 2012-10-10 19:46:56 UTC
Sorry for spaming, I guess anonymous symbols should be tagged with the base version
Comment 11 Igor Pashev 2012-11-09 12:09:32 UTC
It looks like Solaris linker adds soname as a version tag for unversionned symbols:

libbrand.so: undefined reference to `__xmlDoValidityCheckingDefaultValue@libxml2.so.2'

__xmlDoValidityCheckingDefaultValue is not defined in "libxml2.sym" from libxml2 sources.
Comment 12 Igor Pashev 2012-11-09 12:18:59 UTC
(In reply to comment #11)
> It looks like Solaris linker adds soname as a version tag for unversionned
> symbols:
> 
> libbrand.so: undefined reference to
> `__xmlDoValidityCheckingDefaultValue@libxml2.so.2'
> 
> __xmlDoValidityCheckingDefaultValue is not defined in "libxml2.sym" from
> libxml2 sources.

Here: https://github.com/illumos/illumos-gate/blob/master/usr/src/cmd/sgs/libld/common/version.c#L948
Comment 13 Igor Pashev 2012-11-09 19:08:26 UTC
Wow! There is an option --default-symver for ld.
Comment 14 Igor Pashev 2012-11-13 21:10:32 UTC
I think I've fixed this.

The root of the problem is equivalent to this version script:


========================= >8 ================
# "Builtin":
<base name> {
global:
_PROCEDURE_LINKAGE_TABLE_;
_edata;
...
}

# Real mapfile:
{
...
}
========================= 8< ================

So for anonymous version tag we just set base version: (See patch)



Test:


# cat test.c
int foo()
{
    return 17;
}

const char *bar()
{
    return "bar";
}
# cat map
{
    global:
        foo;
    local:
        bar;
};
# gcc -fpic -c test.c -o lib.o -O0
# ld/ld-new -o lib.so lib.o -shared --version-script=map
# objdump -T lib.so 

lib.so:     file format elf64-x86-64-sol2

DYNAMIC SYMBOL TABLE:
0000000000000294 l    d  .text  0000000000000000 .text
0000000000200308 g    DO .dynamic       0000000000000000 _DYNAMIC
0000000000000000 g    DO .text  0000000000000000 _PROCEDURE_LINKAGE_TABLE_
00000000002003b8 l    DO .dynamic       0000000000000000 _END_
0000000000000294 l    DO .text  0000000000000000 _START_
00000000002003b8 g    D  .dynamic       0000000000000000 __bss_start
0000000000000294 g    DF .text  000000000000000b foo
00000000002003b8 g    D  .dynamic       0000000000000000 _edata
0000000000000000 g    DO .dynamic       0000000000000000 _GLOBAL_OFFSET_TABLE_
00000000002003b8 g    D  .dynamic       0000000000000000 _end
Comment 15 Igor Pashev 2012-11-13 21:11:20 UTC
Created attachment 6734 [details]
proposed patch
Comment 16 Igor Pashev 2012-11-13 21:23:26 UTC
*** Bug 13406 has been marked as a duplicate of this bug. ***
Comment 17 Lionel Elie Mamane 2012-11-13 22:50:34 UTC
I confirm that patch in attachment 6734 [details] solves bug 13406 for me (testcase: attachment 6057 [details])
Comment 18 Nikita Baksalyar 2015-12-21 05:50:20 UTC
I can confirm that this bug is still present in binutils 2.25.1 and the proposed patch fixes it.

Any estimates on when it'll be integrated to the master branch?
Comment 19 Nick Clifton 2015-12-22 12:39:56 UTC
Created attachment 8860 [details]
Solaris specific version of previous patch

Hi Guys,

  I think that the problem is that the original patch affects generic linker code, and in a way that is likely to be a regression for other OSes.

  So - please could someone try out this, Solaris specific, version of the patch instead and let me know if it also works.

Cheers
  Nick
Comment 20 Lionel Elie Mamane 2015-12-22 14:35:39 UTC
(In reply to Nick Clifton from comment #19)
> Created attachment 8860 [details]
> Solaris specific version of previous patch

>   I think that the problem is that the original patch affects generic linker
> code, and in a way that is likely to be a regression for other OSes.

Bug 13406 has been marked as a duplicate of this patch, but is not a Solaris-specific patch, so would not be solved by a Solaris-specific patch.