This is for bnc#1075418, a pacemaker libqb problem:

This series fixes PR21964, an incopatiblity with handling
section-start/stop symbols introduced with binutils 2.28.
The pacemaker logging mechanism (libqb) relies on some specifics
that changed with 2.29, and this series reimplements the old
ways (which is also the case for binutils 2.30).

The original bugreport (PR21964) got lost when the bugzilla DB
died at around that time, an archive of the bugzilla traffic is
at http://lists.gnu.org/archive/html/bug-binutils/2017-08/msg00195.html

At the time this was partly fixed for 2.29, but problems remained.
Followup discussion starts:
  https://sourceware.org/ml/binutils/2018-01/msg00265.html
with much more starting at:
  https://sourceware.org/ml/binutils/2018-01/msg00347.html
(of relevance: https://sourceware.org/ml/binutils/2018-01/msg00432.html
for the testcase, and final commit bf3077a6).
  
This patch is basically a concat of backports of these revisions
(plus a bit from fef75122 for testsuite infrastructure):

commit 8dfb7cbf8401be97077f5919ac7473bdbfa8b692
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Tue Aug 22 09:41:21 2017 -0700

    Update PR ld/21964 tests
    
    	* testsuite/ld-elf/pr21964-1a.c (foo): Renamed to ...
    	(foo1): This.
    	* testsuite/ld-elf/pr21964-1b.c: Rewrite.
    	* testsuite/ld-elf/pr21964-1c.c: New file.
    	* testsuite/ld-elf/pr21964-2c.c: Likewise.
    	* testsuite/ld-elf/pr21964-2a.c (foo): Renamed to ...
    	(foo1): This.
    	* testsuite/ld-elf/pr21964-2b.c: Rewrite.
    	* testsuite/ld-elf/shared.exp: Update PR ld/21964 tests.

commit 32253bb7963ac7caa166ec41e336372f2ffc03d4
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Jan 23 10:50:02 2018 +1030

    Define __start/__stop symbols when there is only a dynamic def
    
    This patch fixes a case where a user had a C-representable named
    section in both the executable and shared libraries, and of course
    wanted the size of the local section in the executable, not the
    dynamic section.  It does mean that __start and __stop symbols don't
    behave exactly like PROVIDEd symbols, but I think that's a reasonable
    difference particularly since this is the way they used to behave.
    
    	* elflink.c (bfd_elf_define_start_stop): Override symbols when
    	they are defined dynamically.

commit 36b8fda5d614cb5aaf701a92befa9919bd0b195a
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jan 29 21:45:09 2018 +1030

    Make __start/__stop symbols dynamic and add testcase
    
    bfd/
    	* elflink.c (bfd_elf_define_start_stop): Make __start and __stop
    	symbols dynamic.
    ld/
    	* testsuite/ld-elf/pr21964-3a.c: New file.
    	* testsuite/ld-elf/pr21964-3c.c: New file.
    	* testsuite/ld-elf/shared.exp: Run new __start/__stop testcase.

commit 823143c6ca8ef4267e67ba03771991e08d09fabd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jan 31 05:10:40 2018 -0800

    Check if __start/__stop symbols are referenced by shared objects
    
    Define  __start/__stop symbols if they are referenced by shared objects,
    not if they are also defined in shared objects.
    
    bfd/
    
    	PR ld/21964
    	* elflink.c (bfd_elf_define_start_stop): Check if __start and
    	__stop symbols are referenced by shared objects.
    
    ld/
    
    	PR ld/21964
    	* testsuite/ld-elf/pr21964-4.c: New file.
    	* testsuite/ld-elf/shared.exp: Run pr21964-4 test on Linux.

commit bf3077a6c3c9ff21c072a6f42c91bffefd35bc15
Author: Michael Matz <matz@suse.de>
Date:   Wed Jan 31 14:26:46 2018 +0100

    bfd_elf_define_start_stop: Fix check
    
    We really need to check for a dynamic def, not only a ref.
    See added testcase.
    
    bfd/
    	* elflink.c (bfd_elf_define_start_stop): Fix check of
    	def_dynamic.
    
    ld/
    	* testsuite/ld-elf/pr21964-5.c: New test.
    	* testsuite/ld-elf/shared.exp: Run it.

diff --git a/ld/testsuite/ld-elf/pr21964-1a.c b/ld/testsuite/ld-elf/pr21964-1a.c
index f2eae53..680bda4 100644
--- a/ld/testsuite/ld-elf/pr21964-1a.c
+++ b/ld/testsuite/ld-elf/pr21964-1a.c
@@ -1,6 +1,7 @@
 extern int __start___verbose[];
 extern int __stop___verbose[];
-int foo (void)
+int
+foo1 (void)
 {
   static int my_var __attribute__((used, section("__verbose"))) = 5;
   if (__start___verbose == __stop___verbose
diff --git a/ld/testsuite/ld-elf/pr21964-1b.c b/ld/testsuite/ld-elf/pr21964-1b.c
index 440c937..1507b22 100644
--- a/ld/testsuite/ld-elf/pr21964-1b.c
+++ b/ld/testsuite/ld-elf/pr21964-1b.c
@@ -1,24 +1,12 @@
-#include <stdio.h>
-
-extern int foo (void);
-
 extern int __start___verbose[];
 extern int __stop___verbose[];
-static int my_var __attribute__((used, section("__verbose"))) = 6;
-int bar (void)
+int
+foo2 (void)
 {
-  if (__start___verbose == __stop___verbose)
+  static int my_var __attribute__((used, section("__verbose"))) = 10;
+  if (__start___verbose == __stop___verbose
+      || __start___verbose[0] != 10)
     return -1;
-
-  if (__start___verbose[0] != 6)
-    return -2;
   else
     return 0;
 }
-
-int main()
-{
-  if (bar () == 0 && foo () == 0)
-    printf ("PASS\n");
-  return 0;
-}
diff --git a/ld/testsuite/ld-elf/pr21964-1c.c b/ld/testsuite/ld-elf/pr21964-1c.c
new file mode 100644
index 0000000..996a9e1
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21964-1c.c
@@ -0,0 +1,29 @@
+#include <stdio.h>
+
+extern int foo1 (void);
+extern int foo2 (void);
+
+extern int __start___verbose[];
+extern int __stop___verbose[];
+static int my_var __attribute__((used, section("__verbose"))) = 6;
+int
+bar (void)
+{
+  if (__start___verbose == __stop___verbose)
+    return -1;
+
+  if (__start___verbose[0] != 6)
+    return -2;
+  else
+    return 0;
+}
+
+int
+main ()
+{
+  if (bar () == 0
+      && foo1 () == 0
+      && foo2 () == 0)
+    printf ("PASS\n");
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/pr21964-2a.c b/ld/testsuite/ld-elf/pr21964-2a.c
index 617ce75..6331ff0 100644
--- a/ld/testsuite/ld-elf/pr21964-2a.c
+++ b/ld/testsuite/ld-elf/pr21964-2a.c
@@ -1,6 +1,7 @@
 extern int __start___verbose[];
 extern int __stop___verbose[];
-int foo (void)
+int
+foo1 (void)
 {
   static int my_var __attribute__((used, section("__verbose"))) = 5;
   if (__start___verbose == __stop___verbose
diff --git a/ld/testsuite/ld-elf/pr21964-2b.c b/ld/testsuite/ld-elf/pr21964-2b.c
index 5f638a3..1507b22 100644
--- a/ld/testsuite/ld-elf/pr21964-2b.c
+++ b/ld/testsuite/ld-elf/pr21964-2b.c
@@ -1,27 +1,12 @@
-#include <dlfcn.h>
-#include <stdio.h>
-
-int main()
+extern int __start___verbose[];
+extern int __stop___verbose[];
+int
+foo2 (void)
 {
-  void *dl;
-  void *sym;
-  int (*func) (void);
-
-  dl = dlopen("pr21964-2.so", RTLD_LAZY);
-  if (!dl)
-    return 1;
-
-  sym = dlsym(dl, "__start___verbose");
-  if (!sym)
-    return 2;
-
-  func = dlsym(dl, "foo");
-  if (!func)
-    return 3;
-  if (func () == 0)
-    printf ("PASS\n");
-
-  dlclose(dl);
-
-  return 0;
+  static int my_var __attribute__((used, section("__verbose"))) = 10;
+  if (__start___verbose == __stop___verbose
+      || __start___verbose[0] != 10)
+    return -1;
+  else
+    return 0;
 }
diff --git a/ld/testsuite/ld-elf/pr21964-2c.c b/ld/testsuite/ld-elf/pr21964-2c.c
new file mode 100644
index 0000000..f879dd5
--- /dev/null
+++ b/ld/testsuite/ld-elf/pr21964-2c.c
@@ -0,0 +1,32 @@
+#include <dlfcn.h>
+#include <stdio.h>
+
+extern int foo1 (void);
+
+int main()
+{
+  void *dl;
+  void *sym;
+  int (*func) (void);
+
+  if (foo1 () != 0)
+    return 1;
+
+  dl = dlopen("pr21964-2b.so", RTLD_LAZY);
+  if (!dl)
+    return 2;
+
+  sym = dlsym(dl, "__start___verbose");
+  if (!sym)
+    return 3;
+
+  func = dlsym(dl, "foo2");
+  if (!func)
+    return 4;
+  if (func () == 0)
+    printf ("PASS\n");
+
+  dlclose(dl);
+
+  return 0;
+}
diff --git a/ld/testsuite/ld-elf/shared.exp b/ld/testsuite/ld-elf/shared.exp
index 0802fa2..eee7377 100644
--- a/ld/testsuite/ld-elf/shared.exp
+++ b/ld/testsuite/ld-elf/shared.exp
@@ -423,12 +423,18 @@ set build_tests {
   {"Build libpr19073.so"
    "-shared -Wl,--version-script=pr19073.map tmpdir/pr19073a.o" "-fPIC"
    {dummy.c} {{readelf {--dyn-syms --wide} pr19073.rd}} "libpr19073.so"}
-  {"Build pr21964-1.so"
+  {"Build pr21964-1a.so"
    "-shared" "-fPIC"
-   {pr21964-1a.c} {} "pr21964-1.so"}
-  {"Build pr21964-2.so"
+   {pr21964-1a.c} {} "pr21964-1a.so"}
+  {"Build pr21964-1b.so"
    "-shared" "-fPIC"
-   {pr21964-2a.c} {} "pr21964-2.so"}
+   {pr21964-1b.c} {} "pr21964-1b.so"}
+  {"Build pr21964-2a.so"
+   "-shared" "-fPIC"
+   {pr21964-2a.c} {} "pr21964-2a.so"}
+  {"Build pr21964-2b.so"
+   "-shared" "-fPIC"
+   {pr21964-2b.c} {} "pr21964-2b.so"}
 }
 
 run_cc_link_tests $build_tests
@@ -547,8 +553,8 @@ set run_tests [list \
      "-Wl,--no-as-needed,-z,now tmpdir/libpr18458a.so tmpdir/libpr18458b.so" "" \
      {pr18458c.c} "pr18458" "pass.out" ] \
     [list "Run pr21964-1" \
-     "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-1.so" "" \
-     {pr21964-1b.c} "pr21964-1" "pass.out" ] \
+     "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-1a.so tmpdir/pr21964-1b.so" "" \
+     {pr21964-1c.c} "pr21964-1" "pass.out" ] \
 ]
 
 # NetBSD ELF systems do not currently support the .*_array sections.
@@ -596,8 +602,8 @@ set dlopen_run_tests [list \
      "-Wl,--no-as-needed,--dynamic-list-data $extralibs" "" \
      {dl6dmain.c} "dl6d1" "dl6b.out" ] \
     [list "Run pr21964-2" \
-     "-Wl,--no-as-needed,-rpath,tmpdir $extralibs" "" \
-     {pr21964-2b.c} "pr21964-2" "pass.out" ] \
+     "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-2a.so $extralibs" "" \
+     {pr21964-2c.c} "pr21964-2" "pass.out" ] \
 ]
 
 # Only run them when libdl is available.
commit 32253bb7963ac7caa166ec41e336372f2ffc03d4
Author: Alan Modra <amodra@gmail.com>
Date:   Tue Jan 23 10:50:02 2018 +1030

    Define __start/__stop symbols when there is only a dynamic def
    
    This patch fixes a case where a user had a C-representable named
    section in both the executable and shared libraries, and of course
    wanted the size of the local section in the executable, not the
    dynamic section.  It does mean that __start and __stop symbols don't
    behave exactly like PROVIDEd symbols, but I think that's a reasonable
    difference particularly since this is the way they used to behave.
    
    	* elflink.c (bfd_elf_define_start_stop): Override symbols when
    	they are defined dynamically.

Index: binutils-2.29.1/bfd/elflink.c
===================================================================
--- binutils-2.29.1.orig/bfd/elflink.c	2018-04-03 16:27:33.000000000 +0200
+++ binutils-2.29.1/bfd/elflink.c	2018-04-03 16:28:29.000000000 +0200
@@ -14267,7 +14267,7 @@ bfd_elf_define_start_stop (struct bfd_li
   if (h != NULL
       && (h->root.type == bfd_link_hash_undefined
 	  || h->root.type == bfd_link_hash_undefweak
-	  || (h->ref_regular && !h->def_regular)))
+	  || ((h->ref_regular || h->def_dynamic) && !h->def_regular)))
     {
       h->root.type = bfd_link_hash_defined;
       h->root.u.def.section = sec;
commit 36b8fda5d614cb5aaf701a92befa9919bd0b195a
Author: Alan Modra <amodra@gmail.com>
Date:   Mon Jan 29 21:45:09 2018 +1030

    Make __start/__stop symbols dynamic and add testcase
    
    bfd/
    	* elflink.c (bfd_elf_define_start_stop): Make __start and __stop
    	symbols dynamic.
    ld/
    	* testsuite/ld-elf/pr21964-3a.c: New file.
    	* testsuite/ld-elf/pr21964-3c.c: New file.
    	* testsuite/ld-elf/shared.exp: Run new __start/__stop testcase.

Index: binutils-2.29.1/bfd/elflink.c
===================================================================
--- binutils-2.29.1.orig/bfd/elflink.c	2018-04-03 16:28:34.000000000 +0200
+++ binutils-2.29.1/bfd/elflink.c	2018-04-03 16:28:36.000000000 +0200
@@ -14281,8 +14281,13 @@ bfd_elf_define_start_stop (struct bfd_li
 	  /* .startof. and .sizeof. symbols are local.  */
 	  _bfd_elf_link_hash_hide_symbol (info, h, TRUE);
 	}
-      else if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
-	h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED;
+      else
+	{
+	  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
+	    h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED;
+	  if (h->ref_dynamic || h->def_dynamic)
+	    bfd_elf_link_record_dynamic_symbol (info, h);
+	}
       return &h->root;
     }
   return NULL;
Index: binutils-2.29.1/ld/testsuite/ld-elf/pr21964-3a.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.29.1/ld/testsuite/ld-elf/pr21964-3a.c	2018-04-03 16:28:36.000000000 +0200
@@ -0,0 +1,11 @@
+extern int __start___verbose[];
+extern int __stop___verbose[];
+int
+foo3 (void)
+{
+  if (__start___verbose == __stop___verbose
+      || __start___verbose[0] != 6)
+    return -1;
+  else
+    return 0;
+}
Index: binutils-2.29.1/ld/testsuite/ld-elf/pr21964-3c.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.29.1/ld/testsuite/ld-elf/pr21964-3c.c	2018-04-03 16:28:36.000000000 +0200
@@ -0,0 +1,17 @@
+#include <stdio.h>
+
+extern int foo1 (void);
+extern int foo2 (void);
+extern int foo3 (void);
+
+static int my_var __attribute__((used, section("__verbose"))) = 6;
+
+int
+main ()
+{
+  if (foo1 () == 0
+      && foo2 () == 0
+      && foo3 () == 0)
+    printf ("PASS\n");
+  return 0;
+}
Index: binutils-2.29.1/ld/testsuite/ld-elf/shared.exp
===================================================================
--- binutils-2.29.1.orig/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:28:36.000000000 +0200
+++ binutils-2.29.1/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:29:33.000000000 +0200
@@ -435,6 +435,9 @@ set build_tests {
   {"Build pr21964-2b.so"
    "-shared" "-fPIC"
    {pr21964-2b.c} {} "pr21964-2b.so"}
+  {"Build pr21964-3a.so"
+   "-shared" "-fPIC"
+   {pr21964-3a.c} {} "pr21964-3a.so"}
 }
 
 run_cc_link_tests $build_tests
@@ -555,6 +558,9 @@ set run_tests [list \
     [list "Run pr21964-1" \
      "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-1a.so tmpdir/pr21964-1b.so" "" \
      {pr21964-1c.c} "pr21964-1" "pass.out" ] \
+    [list "Run pr21964-3" \
+     "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-1a.so tmpdir/pr21964-1b.so tmpdir/pr21964-3a.so" "" \
+     {pr21964-3c.c} "pr21964-3" "pass.out" ] \
 ]
 
 # NetBSD ELF systems do not currently support the .*_array sections.
commit 823143c6ca8ef4267e67ba03771991e08d09fabd
Author: H.J. Lu <hjl.tools@gmail.com>
Date:   Wed Jan 31 05:10:40 2018 -0800

    Check if __start/__stop symbols are referenced by shared objects
    
    Define  __start/__stop symbols if they are referenced by shared objects,
    not if they are also defined in shared objects.
    
    bfd/
    
    	PR ld/21964
    	* elflink.c (bfd_elf_define_start_stop): Check if __start and
    	__stop symbols are referenced by shared objects.
    
    ld/
    
    	PR ld/21964
    	* testsuite/ld-elf/pr21964-4.c: New file.
    	* testsuite/ld-elf/shared.exp: Run pr21964-4 test on Linux.

Index: binutils-2.29.1/bfd/elflink.c
===================================================================
--- binutils-2.29.1.orig/bfd/elflink.c	2018-04-03 16:28:36.000000000 +0200
+++ binutils-2.29.1/bfd/elflink.c	2018-04-03 16:29:47.000000000 +0200
@@ -14267,7 +14267,7 @@ bfd_elf_define_start_stop (struct bfd_li
   if (h != NULL
       && (h->root.type == bfd_link_hash_undefined
 	  || h->root.type == bfd_link_hash_undefweak
-	  || ((h->ref_regular || h->def_dynamic) && !h->def_regular)))
+	  || ((h->ref_regular || h->ref_dynamic) && !h->def_regular)))
     {
       h->root.type = bfd_link_hash_defined;
       h->root.u.def.section = sec;
@@ -14285,7 +14285,7 @@ bfd_elf_define_start_stop (struct bfd_li
 	{
 	  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
 	    h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED;
-	  if (h->ref_dynamic || h->def_dynamic)
+	  if (h->ref_dynamic)
 	    bfd_elf_link_record_dynamic_symbol (info, h);
 	}
       return &h->root;
Index: binutils-2.29.1/ld/testsuite/ld-elf/pr21964-4.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.29.1/ld/testsuite/ld-elf/pr21964-4.c	2018-04-03 16:29:47.000000000 +0200
@@ -0,0 +1,22 @@
+#define _GNU_SOURCE
+#include <dlfcn.h>
+#include <stdio.h>
+
+extern int __start___verbose[];
+int bar (void)
+{
+  static int my_var __attribute__ ((section("__verbose"), used)) = 6;
+  int *ptr;
+  ptr = (int*) dlsym (RTLD_DEFAULT, "__start___verbose");
+  if (ptr != NULL || __start___verbose[0] != 6)
+    return -1;
+  return 0;
+}
+
+int
+main ()
+{
+  if (bar () == 0)
+    printf ("PASS\n");
+  return 0;
+}
Index: binutils-2.29.1/ld/testsuite/ld-elf/shared.exp
===================================================================
--- binutils-2.29.1.orig/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:29:33.000000000 +0200
+++ binutils-2.29.1/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:29:47.000000000 +0200
@@ -910,6 +910,18 @@ proc mix_pic_and_non_pic {xfails cflags
 	    "pass.out" \
 	    "$cflags" \
 	] \
+	[list \
+	    "Run pr21964-4" \
+	    "" \
+	    "" \
+	    {pr21964-4.c} \
+	    "pr21964-4" \
+	    "pass.out" \
+	    "" \
+	    "" \
+	    "" \
+	    "-ldl" \
+	] \
     ]
 
     send_log "cp tmpdir/libpr19719a.so tmpdir/libpr19719.so\n"
commit bf3077a6c3c9ff21c072a6f42c91bffefd35bc15
Author: Michael Matz <matz@suse.de>
Date:   Wed Jan 31 14:26:46 2018 +0100

    bfd_elf_define_start_stop: Fix check
    
    We really need to check for a dynamic def, not only a ref.
    See added testcase.
    
    bfd/
    	* elflink.c (bfd_elf_define_start_stop): Fix check of
    	def_dynamic.
    
    ld/
    	* testsuite/ld-elf/pr21964-5.c: New test.
    	* testsuite/ld-elf/shared.exp: Run it.

Index: binutils-2.29.1/bfd/elflink.c
===================================================================
--- binutils-2.29.1.orig/bfd/elflink.c	2018-04-03 16:29:54.000000000 +0200
+++ binutils-2.29.1/bfd/elflink.c	2018-04-03 16:29:56.000000000 +0200
@@ -14267,8 +14267,9 @@ bfd_elf_define_start_stop (struct bfd_li
   if (h != NULL
       && (h->root.type == bfd_link_hash_undefined
 	  || h->root.type == bfd_link_hash_undefweak
-	  || ((h->ref_regular || h->ref_dynamic) && !h->def_regular)))
+	  || ((h->ref_regular || h->def_dynamic) && !h->def_regular)))
     {
+      bfd_boolean was_dynamic = h->ref_dynamic || h->def_dynamic;
       h->root.type = bfd_link_hash_defined;
       h->root.u.def.section = sec;
       h->root.u.def.value = 0;
@@ -14285,7 +14286,7 @@ bfd_elf_define_start_stop (struct bfd_li
 	{
 	  if (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT)
 	    h->other = (h->other & ~ELF_ST_VISIBILITY (-1)) | STV_PROTECTED;
-	  if (h->ref_dynamic)
+	  if (was_dynamic)
 	    bfd_elf_link_record_dynamic_symbol (info, h);
 	}
       return &h->root;
Index: binutils-2.29.1/ld/testsuite/ld-elf/pr21964-5.c
===================================================================
--- /dev/null	1970-01-01 00:00:00.000000000 +0000
+++ binutils-2.29.1/ld/testsuite/ld-elf/pr21964-5.c	2018-04-03 16:29:56.000000000 +0200
@@ -0,0 +1,26 @@
+#define _GNU_SOURCE
+#include <stdlib.h>
+#include <stdio.h>
+#include <dlfcn.h>
+
+extern int foo (void);
+
+extern int __start___verbose[];
+extern int __stop___verbose[];
+int bar (void)
+{
+  static int my_var __attribute__((section("__verbose"))) = 6;
+  int *ptr;
+  ptr = (int*) dlsym(RTLD_DEFAULT, "__start___verbose");
+  if (!ptr || *ptr != 6)
+    return -1;
+  return 0;
+}
+
+int main()
+{
+  if (bar () == 0)
+    printf ("PASS\n");
+
+  return 0;
+}
Index: binutils-2.29.1/ld/testsuite/ld-elf/shared.exp
===================================================================
--- binutils-2.29.1.orig/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:29:56.000000000 +0200
+++ binutils-2.29.1/ld/testsuite/ld-elf/shared.exp	2018-04-03 16:39:45.000000000 +0200
@@ -610,6 +610,9 @@ set dlopen_run_tests [list \
     [list "Run pr21964-2" \
      "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-2a.so $extralibs" "" \
      {pr21964-2c.c} "pr21964-2" "pass.out" ] \
+    [list "Run pr21964-5" \
+     "-Wl,--no-as-needed,-rpath,tmpdir tmpdir/pr21964-1a.so $extralibs" "" \
+     {pr21964-5.c} "pr21964-5" "pass.out" ] \
 ]
 
 # Only run them when libdl is available.
Index: binutils-2.29.1/ld/testsuite/lib/ld-lib.exp
===================================================================
--- binutils-2.29.1.orig/ld/testsuite/lib/ld-lib.exp	2017-07-10 11:54:42.000000000 +0200
+++ binutils-2.29.1/ld/testsuite/lib/ld-lib.exp	2018-04-03 16:42:12.000000000 +0200
@@ -1364,7 +1364,7 @@ if ![string length [info proc prune_warn
 # ldtests contains test-items with 3 items followed by 1 lists, 2 items
 # and 3 optional items:
 #   0:name
-#   1:ld options
+#   1:ld leading options, placed before object files
 #   2:assembler options
 #   3:filenames of source files
 #   4:name of output file
@@ -1372,6 +1372,7 @@ if ![string length [info proc prune_warn
 #   6:compiler flags (optional)
 #   7:language (optional)
 #   8:linker warning (optional)
+#   9:ld trailing options, placed after object files (optional)
 # args is an optional list of target triplets to be xfailed.
 
 proc run_ld_link_exec_tests { ldtests args } {
@@ -1411,6 +1412,7 @@ proc run_ld_link_exec_tests { ldtests ar
 	set cflags [lindex $testitem 6]
 	set lang [lindex $testitem 7]
 	set warning [lindex $testitem 8]
+	set ld_after [lindex $testitem 9]
 	set objfiles {}
 	set failed 0
 
@@ -1453,7 +1455,7 @@ proc run_ld_link_exec_tests { ldtests ar
 	    # compile only
 	    pass $testname
 	    continue;
-	} elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles"] {
+	} elseif ![$link_proc $link_cmd $binfile "$board_cflags -L$srcdir/$subdir $ld_options $objfiles $ld_after"] {
 	    set failed 1
 	}
 
