oldfunc = (h->type != STT_NOTYPE
&& bed->is_function_type (h->type));
- /* If creating a default indirect symbol ("foo" or "foo@") from a
- dynamic versioned definition ("foo@@") skip doing so if there is
- an existing regular definition with a different type. We don't
- want, for example, a "time" variable in the executable overriding
- a "time" function in a shared library. */
- if (pold_alignment == NULL
- && newdyn
- && newdef
- && !olddyn
- && (olddef || h->root.type == bfd_link_hash_common)
+ if (!(newfunc && oldfunc)
&& ELF_ST_TYPE (sym->st_info) != h->type
&& ELF_ST_TYPE (sym->st_info) != STT_NOTYPE
&& h->type != STT_NOTYPE
- && !(newfunc && oldfunc))
+ && (newdef || bfd_is_com_section (sec))
+ && (olddef || h->root.type == bfd_link_hash_common))
{
- *skip = TRUE;
- return TRUE;
+ /* If creating a default indirect symbol ("foo" or "foo@") from
+ a dynamic versioned definition ("foo@@") skip doing so if
+ there is an existing regular definition with a different
+ type. We don't want, for example, a "time" variable in the
+ executable overriding a "time" function in a shared library. */
+ if (newdyn
+ && !olddyn)
+ {
+ *skip = TRUE;
+ return TRUE;
+ }
+
+ /* When adding a symbol from a regular object file after we have
+ created indirect symbols, undo the indirection and any
+ dynamic state. */
+ if (hi != h
+ && !newdyn
+ && olddyn)
+ {
+ h = hi;
+ (*bed->elf_backend_hide_symbol) (info, h, TRUE);
+ h->forced_local = 0;
+ h->ref_dynamic = 0;
+ h->def_dynamic = 0;
+ h->dynamic_def = 0;
+ if (h->root.u.undef.next || info->hash->undefs_tail == &h->root)
+ {
+ h->root.type = bfd_link_hash_undefined;
+ h->root.u.undef.abfd = abfd;
+ }
+ else
+ {
+ h->root.type = bfd_link_hash_new;
+ h->root.u.undef.abfd = NULL;
+ }
+ return TRUE;
+ }
}
/* Check TLS symbols. We don't check undefined symbols introduced
+2017-04-17 Alan Modra <amodra@gmail.com>
+
+ * testsuite/ld-elf/indirect5a.c,
+ * testsuite/ld-elf/indirect5b.c,
+ * testsuite/ld-elf/indirect5.map,
+ * testsuite/ld-elf/indirect5.out: New test.
+ * testsuite/ld-elf/indirect6a.c: Likewise.
+ * testsuite/ld-elf/indirect.exp (check_dynamic_syms): New proc.
+ Run new tests and check dynsyms.
+
2017-04-11 Alan Modra <amodra@gmail.com>
PR 21274
{"Build libindirect4c.so"
"-shared" "-fPIC"
{indirect4c.c} {} "libindirect4c.so"}
+ {"Build libindirect5.so"
+ "-shared -Wl,--version-script=indirect5.map" "-fPIC"
+ {indirect5b.c} {} "libindirect5.so"}
{"Build libpr18720c.so"
"-shared" "-fPIC"
{pr18720c.c} {} "libpr18720c.so"}
{"Run with libindirect4c.so 4"
"-Wl,--no-as-needed tmpdir/libindirect4c.so tmpdir/indirect4b.o tmpdir/indirect4a.o" ""
{dummy.c} "indirect4d" "indirect4.out"}
+ {"Run indirect5 1"
+ "-Wl,--no-as-needed tmpdir/libindirect5.so" ""
+ {indirect5a.c} "indirect5a" "indirect5.out"}
+ {"Run indirect5 2"
+ "-Wl,--no-as-needed tmpdir/indirect5a.o tmpdir/libindirect5.so" ""
+ {dummy.c} "indirect5b" "indirect5.out"}
+ {"Run indirect6 1"
+ "-Wl,--no-as-needed tmpdir/libindirect5.so" ""
+ {indirect6a.c} "indirect6a" "indirect5.out"}
+ {"Run indirect6 2"
+ "-Wl,--no-as-needed tmpdir/indirect6a.o tmpdir/libindirect5.so" ""
+ {dummy.c} "indirect6b" "indirect5.out"}
{"Run with libpr18720c.so 1"
"-Wl,--no-as-needed tmpdir/pr18720a.o tmpdir/pr18720b.o tmpdir/libpr18720c.so" ""
{check-ptr-eq.c} "pr18720a" "pr18720.out"}
}
run_ld_link_exec_tests $run_tests
+
+# Check that "bar" is not dynamic in the executable
+proc check_dynamic_syms { test } {
+ global nm
+ set cmd "$nm -D $test > dump.out"
+ send_log "$cmd\n"
+ catch "exec $cmd" comp_output
+ if ![string match "" $comp_output] then {
+ send_log "$comp_output\n"
+ return 0
+ }
+ if { [string match "* bar\n*" [file_contents "dump.out"]] } then {
+ verbose "output is [file_contents "dump.out"]"
+ return 0
+ }
+ return 1
+}
+
+foreach t [list indirect5a indirect5b indirect6a indirect6b] {
+ set testname [concat $t "dynsym"]
+ if { [check_dynamic_syms tmpdir/$t] } {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}
+
+send_log "$CC -fPIE -pie $srcdir/$subdir/main.c -o tmpdir/pie"
+catch "exec $CC -fPIE -pie $srcdir/$subdir/main.c -o tmpdir/pie" exec_output
+send_log "$exec_output"
+if { ! [string match "" $exec_output] } {
+ return
+}
+
+set pie_tests {
+ {"Run indirect5 3"
+ "-pie -Wl,--no-as-needed tmpdir/libindirect5.so" ""
+ {indirect5a.c} "indirect5c" "indirect5.out" "-fPIE"}
+ {"Run indirect5 4"
+ "-pie -Wl,--no-as-needed tmpdir/indirect5a.o tmpdir/libindirect5.so" ""
+ {dummy.c} "indirect5d" "indirect5.out" "-fPIE"}
+ {"Run indirect6 3"
+ "-pie -Wl,--no-as-needed tmpdir/libindirect5.so" ""
+ {indirect6a.c} "indirect6c" "indirect5.out" "-fPIE"}
+ {"Run indirect6 4"
+ "-pie -Wl,--no-as-needed tmpdir/indirect6a.o tmpdir/libindirect5.so" "-fPIE"
+ {dummy.c} "indirect6d" "indirect5.out" "-fPIE"}
+}
+
+run_ld_link_exec_tests $pie_tests
+
+foreach t [list indirect5c indirect5d indirect6c indirect6d] {
+ set testname [concat $t "dynsym"]
+ if { [check_dynamic_syms tmpdir/$t] } {
+ pass $testname
+ } else {
+ fail $testname
+ }
+}