[hjl@gnu-6 gotplt-4]$ cat a.c #include <stdio.h> void a (void) { printf("Hello, World!\n"); } [hjl@gnu-6 gotplt-4]$ cat b.c extern void a (void); void b (void) { a(); } [hjl@gnu-6 gotplt-4]$ cat main.c extern void a(void); extern void b(void); void dummy (void) { a(); } int compare (void (*f)(void)) { return a == f; } int main (void) { b (); return 0; } [hjl@gnu-6 gotplt-4]$ make gcc -m32 -O -g -c -o main.o main.c gcc -m32 -O -g -fpic -o a.o -c a.c gcc -m32 -O -g -Wl,-z,now -shared -o a.so a.o gcc -m32 -O -g -fpic -o b.o -c b.c gcc -m32 -O -g -Wl,-z,now -shared -o b.so b.o a.so gcc -m32 -O -g -Wl,-rpath=. -Wl,-z,now -o main main.o a.so b.so [hjl@gnu-6 gotplt-4]$ ./main "main" enters an infinite loop.
The master branch has been updated by H.J. Lu <hjl@sourceware.org>: https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=8ded2ddc8bac501c1ee0706cb3d3ef3fb1c10b85 commit 8ded2ddc8bac501c1ee0706cb3d3ef3fb1c10b85 Author: H.J. Lu <hjl.tools@gmail.com> Date: Wed May 27 14:32:24 2015 -0700 Convert PLT reloc only if pointer equality isn't needed When pointer equality needed, we can't replace PLT relocations with GOT relocations for -z now. This patch checks if pointer equality is needed before converting PLT relocations to GOT relocations. bfd/ PR binutils/18458 * elf32-i386.c (elf_i386_check_relocs): Create .plt.got section for now binding only if pointer equality isn't needed. (elf_i386_allocate_dynrelocs): Use .plt.got section for now binding only if pointer equality isn't needed. * elf64-x86-64.c (elf_x86_64_check_relocs): Create .plt.got section for now binding only if pointer equality isn't needed. (elf_x86_64_allocate_dynrelocs): Use .plt.got section for now binding only if pointer equality isn't needed. ld/testsuite/ PR binutils/18458 * ld-elf/shared.exp (build_tests): Build libpr18458a.so and libpr18458b.so. (run_tests): Run pr18458 test. * ld-elf/pr18458a.c: New file. * ld-elf/pr18458b.c: Likewise. * ld-elf/pr18458c.c: Likewise.
Fixed.