Binutils cannot be used to build Glibc since this commit: commit 422f11824b3abf6c71042e2ee3aed572f250fc89 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Aug 10 07:57:40 2015 -0700 Replace hidden with versioned in elf_link_hash_entry This patch replaces the "hidden" field with the "versioned" field in elf_link_hash_entry so that we can avoid calling strchr and strrchr if the symbol is unversioned. * elf-bfd.h (elf_symbol_version): New enum. (elf_link_hash_entry): Replace hidden with versioned. * elflink.c (_bfd_elf_merge_symbol): Don't look for symbol version if the symbol is unversioned. Initialize versioned. (_bfd_elf_add_default_symbol): Don't look for symbol version if the symbol is unversioned or hidden. Initialize versioned. (elf_collect_hash_codes): Don't look for symbol version if the symbol is unversioned. (elf_collect_gnu_hash_codes): Likewise. (bfd_elf_gc_mark_dynamic_ref_symbol): Likewise. (_bfd_elf_link_hash_copy_indirect): Check versioned instead of hidden. (elf_link_output_extsym): Likewise. gcc -shared -static-libgcc -Wl,-O1 -Wl,-z,defs -Wl,-dynamic-linker=/lib/ld64.so.1 -B/home/andreas/glibc/glibc-06102015-build/csu/ -Wl,--version-script=/home/andreas/glibc/glibc-06102015-build/libc.map -Wl,-soname=libc.so.6 -Wl,-z,combreloc -Wl,-z,relro -Wl,--hash-style=both -nostdlib -nostartfiles -e __libc_main -L/home/andreas/glibc/glibc-06102015-build -L/home/andreas/glibc/glibc-06102015-build/math -L/home/andreas/glibc/glibc-06102015-build/elf -L/home/andreas/glibc/glibc-06102015-build/dlfcn -L/home/andreas/glibc/glibc-06102015-build/nss -L/home/andreas/glibc/glibc-06102015-build/nis -L/home/andreas/glibc/glibc-06102015-build/rt -L/home/andreas/glibc/glibc-06102015-build/resolv -L/home/andreas/glibc/glibc-06102015-build/crypt -L/home/andreas/glibc/glibc-06102015-build/mathvec -L/home/andreas/glibc/glibc-06102015-build/nptl -Wl,-rpath-link=/home/andreas/glibc/glibc-06102015-build:/home/andreas/glibc/glibc-06102015-build/math:/home/andreas/glibc/glibc-06102015-build/elf:/home/andreas/glibc/glibc-06102015-build/dlfcn:/home/andreas/glibc/glibc-06102015-build/nss:/home/andreas/glibc/glibc-06102015-build/nis:/home/andreas/glibc/glibc-06102015-build/rt:/home/andreas/glibc/glibc-06102015-build/resolv:/home/andreas/glibc/glibc-06102015-build/crypt:/home/andreas/glibc/glibc-06102015-build/mathvec:/home/andreas/glibc/glibc-06102015-build/nptl -o /home/andreas/glibc/glibc-06102015-build/libc.so -T /home/andreas/glibc/glibc-06102015-build/shlib.lds /home/andreas/glibc/glibc-06102015-build/csu/abi-note.o /home/andreas/glibc/glibc-06102015-build/elf/soinit.os /home/andreas/glibc/glibc-06102015-build/libc_pic.os /home/andreas/glibc/glibc-06102015-build/elf/sofini.os /home/andreas/glibc/glibc-06102015-build/elf/interp.os /home/andreas/glibc/glibc-06102015-build/elf/ld.so -lgcc /bin/sh ../scripts/rellns-sh /home/andreas/glibc/glibc-06102015-build/elf/ld.so /home/andreas/glibc/glibc-06102015-build/elf/ld64.so.1.new mv -f /home/andreas/glibc/glibc-06102015-build/elf/ld64.so.1.new /home/andreas/glibc/glibc-06102015-build/elf/ld64.so.1 collect2: error: ld terminated with signal 11 [Segmentation fault] make[2]: *** [/home/andreas/glibc/glibc-06102015-build/libc.so] Error 1 make[2]: Leaving directory `/home/andreas/glibc/glibc/elf' make[1]: *** [elf/subdir_lib] Error 2 make[1]: Leaving directory `/home/andreas/glibc/glibc' make: *** [all] Error 2 Program received signal SIGSEGV, Segmentation fault. 0x000003fffdeb323c in __memcpy_mvcle () from /lib64/libc.so.6 (gdb) bt #0 0x000003fffdeb323c in __memcpy_mvcle () from /lib64/libc.so.6 #1 0x000000008009ae06 in _bfd_elf_add_default_symbol (abfd=0x8022f050, info=0x801be990 <link_info>, h=0x802b02f8, name=0x8024bab7 "setjmp", sym=0x3fff78d22d0, sec=0x80230320, value=86064, poldbfd=0x3ffffffddd0, dynsym=0x3ffffffddc0) at /home/andreas/binutils/binutils/bfd/elflink.c:1724 #2 0x00000000800a1752 in elf_link_add_object_symbols (abfd=0x8022f050, info=0x801be990 <link_info>) at /home/andreas/binutils/binutils/bfd/elflink.c:4375 #3 0x00000000800a3918 in bfd_elf_link_add_symbols (abfd=0x8022f050, info=0x801be990 <link_info>) at /home/andreas/binutils/binutils/bfd/elflink.c:5241 #4 0x0000000080015580 in load_symbols (entry=0x801c0328, place=0x3ffffffe438) at /home/andreas/binutils/binutils/ld/ldlang.c:2854 #5 0x0000000080016790 in open_input_bfds (s=0x801c0328, mode=OPEN_BFD_NORMAL) at /home/andreas/binutils/binutils/ld/ldlang.c:3311 #6 0x000000008001ebe4 in lang_process () at /home/andreas/binutils/binutils/ld/ldlang.c:6677 #7 0x0000000080024c06 in main (argc=50, argv=0x3ffffffe898) at /home/andreas/binutils/binutils/ld/ldmain.c:419
I can build glibc master branch with binutils 2.25.51.20151006 on x86 and x86-64. What target were you building for?
(In reply to H.J. Lu from comment #1) > I can build glibc master branch with binutils 2.25.51.20151006 on > x86 and x86-64. What target were you building for? s390x - I definitely should have mentioned this - sorry
What went wrong?
(gdb) p name $1 = 0x8024eab7 "setjmp" (gdb) p shortname $2 = 0x3ff77b15020 "setjmp" (gdb) p shortlen $3 = 18446744071559648585 (gdb) l 1722 1723 shortlen = p - name; 1724 shortname = (char *) bfd_hash_allocate (&info->hash->table, shortlen + 1); 1725 if (shortname == NULL) 1726 return FALSE; 1727 memcpy (shortname, name, shortlen); 1728 shortname[shortlen] = '\0'; 1729 1730 /* We are going to create a new symbol. Merge it with any existing 1731 symbol with this name. For the purposes of the merge, act as (gdb) p p $4 = 0x0 (gdb) p name $5 = 0x8024eab7 "setjmp" (gdb) p h->versioned $6 = versioned The problem is that there might be symbols marked as versioned but without having @ in its names. p is NULL then. We have that with setjmp in Glibc: 234157: 0000000000015030 8 FUNC WEAK DEFAULT 2 setjmp@@GLIBC_2.2 234509: 0000000000015030 8 FUNC WEAK DEFAULT 2 setjmp
(In reply to Andreas Krebbel from comment #4) > > The problem is that there might be symbols marked as versioned but without > having @ in its names. p is NULL then. > > We have that with setjmp in Glibc: > 234157: 0000000000015030 8 FUNC WEAK DEFAULT 2 setjmp@@GLIBC_2.2 > 234509: 0000000000015030 8 FUNC WEAK DEFAULT 2 setjmp Please provide a testcase.
Created attachment 8701 [details] Testcase - reduced input file from glibc With this testcase the failing symbol is getcontext: 16488: 0000000000000000 106 FUNC WEAK DEFAULT 2 __v1__getcontext 16534: 0000000000000000 106 FUNC GLOBAL DEFAULT 2 __getcontext 16562: 0000000000000000 106 FUNC WEAK DEFAULT 2 getcontext@@GLIBC_2.2 16570: 0000000000000000 106 FUNC WEAK DEFAULT 2 getcontext@GLIBC_2.19 16589: 0000000000000000 106 FUNC WEAK DEFAULT 2 __v2__getcontext 16660: 0000000000000000 106 FUNC WEAK DEFAULT 2 getcontext getcontext (as well as setjmp and others) on S/390 default to an older symbol version in order to avoid the buggy versions in Glibc 2.19.
Please provide a testcase I can reproduce it on x86-64 with only cross binutils.
(In reply to H.J. Lu from comment #7) > Please provide a testcase I can reproduce it on x86-64 with > only cross binutils. The testcase I've attached fails the same way with cross binutils: install-s390x/bin/s390x-ibm-linux-ld -melf64_s390 b.os Segmentation fault (core dumped)
The problem is that when processing "getcontext" in elf_link_add_object_symbols it is matched by the hash entry for "getcontext@@GLIBC_2.2" here: /* We need to make sure that indirect symbol dynamic flags are updated. */ hi = h; while (h->root.type == bfd_link_hash_indirect || h->root.type == bfd_link_hash_warning) h = (struct elf_link_hash_entry *) h->root.u.i.link; While the name stays "getcontext" the new `h' has the `versioned' flag set. That's what confuses _bfd_elf_add_default_symbol. This hack mimics the old behavior of exiting for all symbols not having @ in their name and fixes the problem for me: diff --git a/bfd/elflink.c b/bfd/elflink.c index 94bb710..2a56fd6 100644 --- a/bfd/elflink.c +++ b/bfd/elflink.c @@ -4374,8 +4374,9 @@ error_free_dyn: /* Check to see if we need to add an indirect symbol for the default name. */ - if (definition - || (!override && h->root.type == bfd_link_hash_common)) + if (strchr (name, ELF_VER_CHR) != NULL + && (definition + || (!override && h->root.type == bfd_link_hash_common))) if (!_bfd_elf_add_default_symbol (abfd, info, h, name, isym, sec, value, &old_bfd, &dynsym)) goto error_free_vers;
(In reply to Andreas Krebbel from comment #8) > (In reply to H.J. Lu from comment #7) > > Please provide a testcase I can reproduce it on x86-64 with > > only cross binutils. > > The testcase I've attached fails the same way with cross binutils: > > install-s390x/bin/s390x-ibm-linux-ld -melf64_s390 b.os > Segmentation fault (core dumped) [hjl@gnu-6 pr19073]$ cat xxx.c void __foo () { } asm (".weak foo_v1"); asm (".globl foo_v1"); asm (".set foo_v1, __foo"); asm (".weak foo_v2"); asm (".globl foo_v2"); asm (".set foo_v2, __foo"); asm (".symver foo_v2,foo@VERS.2"); asm (".symver foo_v1,foo@@VERS.1"); asm (".globl foo"); asm (".weak foo"); asm (".set foo, __foo"); [hjl@gnu-6 pr19073]$ make libfoo.so gcc -B./ -fPIC -c -o xxx.o xxx.c ./ld -o foo.o -r xxx.o ./ld -o libfoo.so -shared foo.o --version-script foo.v Makefile:12: recipe for target 'libfoo.so' failed make: *** [libfoo.so] Segmentation fault make: *** Deleting file 'libfoo.so' [hjl@gnu-6 pr19073]$ There is a bug in sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S which defines both getcontext@@GLIBC_2.2 and getcontext. But linker shouldn't crash.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=4373f8af3ddbc301227e883d5cbed8302c107e59 commit 4373f8af3ddbc301227e883d5cbed8302c107e59 Author: H.J. Lu <hjl.tools@gmail.com> Date: Mon Oct 12 04:55:24 2015 -0700 Skip the unversioned definition after the default version We may see an unversioned definition after the default version. We should skip the unversioned definition in this case. bfd/ PR ld/19073 * elflink.c (_bfd_elf_add_default_symbol): Skip the unversioned definition after the default version. ld/testsuite/ PR ld/19073 * ld-elf/pr19073.map: New file. * ld-elf/pr19073.rd: Likewise. * ld-elf/pr19073.s: Likewise. * ld-elf/shared.exp (build_tests): Add tests for PR ld/19073.
Fixed.
(In reply to H.J. Lu from comment #10) > (In reply to Andreas Krebbel from comment #8) > > (In reply to H.J. Lu from comment #7) > > > Please provide a testcase I can reproduce it on x86-64 with > > > only cross binutils. > > > > The testcase I've attached fails the same way with cross binutils: > > > > install-s390x/bin/s390x-ibm-linux-ld -melf64_s390 b.os > > Segmentation fault (core dumped) > > [hjl@gnu-6 pr19073]$ cat xxx.c > void > __foo () > { > } > > asm (".weak foo_v1"); > asm (".globl foo_v1"); > asm (".set foo_v1, __foo"); > asm (".weak foo_v2"); > asm (".globl foo_v2"); > asm (".set foo_v2, __foo"); > asm (".symver foo_v2,foo@VERS.2"); > asm (".symver foo_v1,foo@@VERS.1"); > asm (".globl foo"); > asm (".weak foo"); > asm (".set foo, __foo"); > [hjl@gnu-6 pr19073]$ make libfoo.so > gcc -B./ -fPIC -c -o xxx.o xxx.c > ./ld -o foo.o -r xxx.o > ./ld -o libfoo.so -shared foo.o --version-script foo.v > Makefile:12: recipe for target 'libfoo.so' failed > make: *** [libfoo.so] Segmentation fault > make: *** Deleting file 'libfoo.so' > [hjl@gnu-6 pr19073]$ > > There is a bug in sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S > which defines both getcontext@@GLIBC_2.2 and getcontext. But linker > shouldn't crash. I agree that this does not look correct but it is similiar to e.g. setjmp on x86_64: readelf -s libc.so.6 | grep " setjmp" 622: 0000000000032ce0 10 FUNC GLOBAL DEFAULT 13 setjmp@@GLIBC_2.2.5 6015: 0000000000032ce0 10 FUNC GLOBAL DEFAULT 13 setjmp One difference appears to be that the symbol without version information is weak on s390.
(In reply to Andreas Krebbel from comment #13) > > There is a bug in sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S > > which defines both getcontext@@GLIBC_2.2 and getcontext. But linker > > shouldn't crash. > > I agree that this does not look correct but it is similiar to e.g. setjmp on > x86_64: > > readelf -s libc.so.6 | grep " setjmp" > 622: 0000000000032ce0 10 FUNC GLOBAL DEFAULT 13 > setjmp@@GLIBC_2.2.5 > 6015: 0000000000032ce0 10 FUNC GLOBAL DEFAULT 13 setjmp This is expected. > One difference appears to be that the symbol without version information is > weak on s390. I was referring to the input object files, not output shared libraries. There is no need to define both getcontext@@GLIBC_2.2 and getcontext in sysdeps/unix/sysv/linux/s390/s390-64/getcontext.S.