summaryrefslogtreecommitdiff
path: root/ld
diff options
context:
space:
mode:
Diffstat (limited to 'ld')
-rw-r--r--ld/emultempl/elf32.em2
-rw-r--r--ld/ld.texinfo4
-rw-r--r--ld/ldmain.c1
-rw-r--r--ld/lexsup.c2
-rw-r--r--ld/testsuite/ld-elf/library1.c11
-rw-r--r--ld/testsuite/ld-elf/library1.out1
-rw-r--r--ld/testsuite/ld-elf/library2.c12
-rw-r--r--ld/testsuite/ld-elf/library2.out1
-rw-r--r--ld/testsuite/ld-elf/library3.out1
-rw-r--r--ld/testsuite/ld-elf/library4.out1
-rw-r--r--ld/testsuite/ld-elf/library5a.c16
-rw-r--r--ld/testsuite/ld-elf/library5b.c10
-rw-r--r--ld/testsuite/ld-elf/library6a.c4
-rw-r--r--ld/testsuite/ld-elf/library6b.c7
-rw-r--r--ld/testsuite/ld-elf/library6c.c9
-rw-r--r--ld/testsuite/ld-elf/library7a.c1
-rw-r--r--ld/testsuite/ld-elf/library7b.c7
-rw-r--r--ld/testsuite/ld-elf/library7c.c3
-rw-r--r--ld/testsuite/ld-elf/library8.map4
-rw-r--r--ld/testsuite/ld-elf/library8a.c10
-rw-r--r--ld/testsuite/ld-elf/library8a.rd5
-rw-r--r--ld/testsuite/ld-elf/library8b.c4
-rw-r--r--ld/testsuite/ld-elf/library8b.rd5
-rw-r--r--ld/testsuite/ld-elf/library8c.c7
-rw-r--r--ld/testsuite/ld-elf/library8c.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary-foo.c7
-rw-r--r--ld/testsuite/ld-elf/secondary-main.c8
-rw-r--r--ld/testsuite/ld-elf/secondary.c9
-rw-r--r--ld/testsuite/ld-elf/secondary.exp186
-rw-r--r--ld/testsuite/ld-elf/secondary.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary1.out1
-rw-r--r--ld/testsuite/ld-elf/secondary1.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary2.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary3.rd6
-rw-r--r--ld/testsuite/ld-elf/secondary3a.s4
-rw-r--r--ld/testsuite/ld-elf/secondary3b.s20
-rw-r--r--ld/testsuite/ld-elf/secondary4.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary4.s9
-rw-r--r--ld/testsuite/ld-elf/secondary5.c10
-rw-r--r--ld/testsuite/ld-elf/secondary5.out3
-rw-r--r--ld/testsuite/ld-elf/secondary6.c11
-rw-r--r--ld/testsuite/ld-elf/secondary6.out1
-rw-r--r--ld/testsuite/ld-elf/secondary7.c13
-rw-r--r--ld/testsuite/ld-elf/secondary7.out1
-rw-r--r--ld/testsuite/ld-elf/secondary8a.c13
-rw-r--r--ld/testsuite/ld-elf/secondary8a.map4
-rw-r--r--ld/testsuite/ld-elf/secondary8a.rd5
-rw-r--r--ld/testsuite/ld-elf/secondary8b.c13
-rw-r--r--ld/testsuite/ld-elf/secondary8b.rd5
49 files changed, 482 insertions, 0 deletions
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 7fe90894e8f..23833669386 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2385,6 +2385,8 @@ fragment <<EOF
link_info.error_textrel = FALSE;
else if (strcmp (optarg, "textoff") == 0)
link_info.error_textrel = FALSE;
+ else if (strcmp (optarg, "nosecondary") == 0)
+ link_info.emit_secondary = FALSE;
EOF
fi
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index be1d4906fae..bb9408de5ee 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -1177,6 +1177,10 @@ Marks the object may contain $ORIGIN.
@item relro
Create an ELF @code{PT_GNU_RELRO} segment header in the object.
+@item nosecondary
+Convert secondary symbols to weak symbols when generating a shared
+library.
+
@item max-page-size=@var{value}
Set the emulation maximum page size to @var{value}.
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 577928d5504..4c2b5a03440 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -278,6 +278,7 @@ main (int argc, char **argv)
link_info.combreloc = TRUE;
link_info.strip_discarded = TRUE;
link_info.emit_hash = TRUE;
+ link_info.emit_secondary = TRUE;
link_info.callbacks = &link_callbacks;
link_info.input_bfds_tail = &link_info.input_bfds;
/* SVR4 linkers seem to set DT_INIT and DT_FINI based on magic _init
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 5dc56dc148e..536296d0e91 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1732,6 +1732,8 @@ elf_shlib_list_options (FILE *file)
fprintf (file, _("\
-z norelro Don't create RELRO program header\n"));
fprintf (file, _("\
+ -z nosecondary Convert secondary symbols to weak symbols\n"));
+ fprintf (file, _("\
-z stacksize=SIZE Set size of stack segment\n"));
fprintf (file, _("\
-z text Treat DT_TEXTREL in shared object as error\n"));
diff --git a/ld/testsuite/ld-elf/library1.c b/ld/testsuite/ld-elf/library1.c
new file mode 100644
index 00000000000..28e255d318f
--- /dev/null
+++ b/ld/testsuite/ld-elf/library1.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+void
+bar (void)
+{
+#ifdef SHARED
+ printf ("library bar (SHARED)\n");
+#else
+ printf ("library bar\n");
+#endif
+}
diff --git a/ld/testsuite/ld-elf/library1.out b/ld/testsuite/ld-elf/library1.out
new file mode 100644
index 00000000000..2050e746e5a
--- /dev/null
+++ b/ld/testsuite/ld-elf/library1.out
@@ -0,0 +1 @@
+library bar
diff --git a/ld/testsuite/ld-elf/library2.c b/ld/testsuite/ld-elf/library2.c
new file mode 100644
index 00000000000..271ebd6ef1a
--- /dev/null
+++ b/ld/testsuite/ld-elf/library2.c
@@ -0,0 +1,12 @@
+#include <stdio.h>
+
+void
+__attribute__((weak))
+bar (void)
+{
+#ifdef SHARED
+ printf ("weak library bar (SHARED)\n");
+#else
+ printf ("weak library bar\n");
+#endif
+}
diff --git a/ld/testsuite/ld-elf/library2.out b/ld/testsuite/ld-elf/library2.out
new file mode 100644
index 00000000000..ddd3d10e794
--- /dev/null
+++ b/ld/testsuite/ld-elf/library2.out
@@ -0,0 +1 @@
+weak library bar
diff --git a/ld/testsuite/ld-elf/library3.out b/ld/testsuite/ld-elf/library3.out
new file mode 100644
index 00000000000..881856e6639
--- /dev/null
+++ b/ld/testsuite/ld-elf/library3.out
@@ -0,0 +1 @@
+library bar (SHARED)
diff --git a/ld/testsuite/ld-elf/library4.out b/ld/testsuite/ld-elf/library4.out
new file mode 100644
index 00000000000..1ff18403d51
--- /dev/null
+++ b/ld/testsuite/ld-elf/library4.out
@@ -0,0 +1 @@
+weak library bar (SHARED)
diff --git a/ld/testsuite/ld-elf/library5a.c b/ld/testsuite/ld-elf/library5a.c
new file mode 100644
index 00000000000..7e44bb4b578
--- /dev/null
+++ b/ld/testsuite/ld-elf/library5a.c
@@ -0,0 +1,16 @@
+#include <stdio.h>
+
+asm (".secondary bar");
+asm (".weak bar");
+
+void
+bar (void)
+{
+ printf ("secondary bar\n");
+}
+
+void
+xxx (void)
+{
+ printf ("xxx\n");
+}
diff --git a/ld/testsuite/ld-elf/library5b.c b/ld/testsuite/ld-elf/library5b.c
new file mode 100644
index 00000000000..f44d97c2ad8
--- /dev/null
+++ b/ld/testsuite/ld-elf/library5b.c
@@ -0,0 +1,10 @@
+#include <stdio.h>
+
+extern void bar (void);
+
+void
+foo (void)
+{
+ printf ("foo\n");
+ bar ();
+}
diff --git a/ld/testsuite/ld-elf/library6a.c b/ld/testsuite/ld-elf/library6a.c
new file mode 100644
index 00000000000..7de81b31a47
--- /dev/null
+++ b/ld/testsuite/ld-elf/library6a.c
@@ -0,0 +1,4 @@
+void
+bar (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/library6b.c b/ld/testsuite/ld-elf/library6b.c
new file mode 100644
index 00000000000..528fd893305
--- /dev/null
+++ b/ld/testsuite/ld-elf/library6b.c
@@ -0,0 +1,7 @@
+extern void bar (void);
+
+void
+xxx (void)
+{
+ bar ();
+}
diff --git a/ld/testsuite/ld-elf/library6c.c b/ld/testsuite/ld-elf/library6c.c
new file mode 100644
index 00000000000..60f4b922ad4
--- /dev/null
+++ b/ld/testsuite/ld-elf/library6c.c
@@ -0,0 +1,9 @@
+extern void abort (void);
+
+asm (".secondary bar");
+
+void
+bar (void)
+{
+ abort ();
+}
diff --git a/ld/testsuite/ld-elf/library7a.c b/ld/testsuite/ld-elf/library7a.c
new file mode 100644
index 00000000000..10cd8bfee26
--- /dev/null
+++ b/ld/testsuite/ld-elf/library7a.c
@@ -0,0 +1 @@
+int bar;
diff --git a/ld/testsuite/ld-elf/library7b.c b/ld/testsuite/ld-elf/library7b.c
new file mode 100644
index 00000000000..5f67848a29f
--- /dev/null
+++ b/ld/testsuite/ld-elf/library7b.c
@@ -0,0 +1,7 @@
+extern int bar;
+
+int
+xxx (void)
+{
+ return bar;
+}
diff --git a/ld/testsuite/ld-elf/library7c.c b/ld/testsuite/ld-elf/library7c.c
new file mode 100644
index 00000000000..aa57fde8197
--- /dev/null
+++ b/ld/testsuite/ld-elf/library7c.c
@@ -0,0 +1,3 @@
+asm (".secondary bar");
+
+int bar = 3;
diff --git a/ld/testsuite/ld-elf/library8.map b/ld/testsuite/ld-elf/library8.map
new file mode 100644
index 00000000000..bcbb4dea890
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8.map
@@ -0,0 +1,4 @@
+VERS_1 {
+ global: bar; _bar;
+ local: *;
+};
diff --git a/ld/testsuite/ld-elf/library8a.c b/ld/testsuite/ld-elf/library8a.c
new file mode 100644
index 00000000000..29a75087a02
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8a.c
@@ -0,0 +1,10 @@
+#if 1
+asm (".secondary bar");
+#else
+asm (".weak bar");
+#endif
+
+void
+bar (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/library8a.rd b/ld/testsuite/ld-elf/library8a.rd
new file mode 100644
index 00000000000..a593fbdc2cf
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8a.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar@@VERS_1
+#...
diff --git a/ld/testsuite/ld-elf/library8b.c b/ld/testsuite/ld-elf/library8b.c
new file mode 100644
index 00000000000..7de81b31a47
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8b.c
@@ -0,0 +1,4 @@
+void
+bar (void)
+{
+}
diff --git a/ld/testsuite/ld-elf/library8b.rd b/ld/testsuite/ld-elf/library8b.rd
new file mode 100644
index 00000000000..fc18d1ad625
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8b.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +GLOBAL +DEFAULT +[0-9]+ +_?bar@@VERS_1
+#...
diff --git a/ld/testsuite/ld-elf/library8c.c b/ld/testsuite/ld-elf/library8c.c
new file mode 100644
index 00000000000..dfb6a22edb8
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8c.c
@@ -0,0 +1,7 @@
+extern void bar ();
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/ld/testsuite/ld-elf/library8c.rd b/ld/testsuite/ld-elf/library8c.rd
new file mode 100644
index 00000000000..e2e58f021bb
--- /dev/null
+++ b/ld/testsuite/ld-elf/library8c.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +0+ +0+ +FUNC +GLOBAL +DEFAULT +UND +_?bar@VERS_1 +\([0-9]+\)
+#...
diff --git a/ld/testsuite/ld-elf/secondary-foo.c b/ld/testsuite/ld-elf/secondary-foo.c
new file mode 100644
index 00000000000..8b23ec8f2b7
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary-foo.c
@@ -0,0 +1,7 @@
+extern void bar (void);
+
+void
+foo (void)
+{
+ bar ();
+}
diff --git a/ld/testsuite/ld-elf/secondary-main.c b/ld/testsuite/ld-elf/secondary-main.c
new file mode 100644
index 00000000000..f1cb6b492bd
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary-main.c
@@ -0,0 +1,8 @@
+extern void foo (void);
+
+int
+main (void)
+{
+ foo ();
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/secondary.c b/ld/testsuite/ld-elf/secondary.c
new file mode 100644
index 00000000000..6d64ed7652e
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary.c
@@ -0,0 +1,9 @@
+#include <stdio.h>
+
+asm (".secondary bar");
+
+void
+bar (void)
+{
+ printf ("secondary bar\n");
+}
diff --git a/ld/testsuite/ld-elf/secondary.exp b/ld/testsuite/ld-elf/secondary.exp
new file mode 100644
index 00000000000..2518db3c0a0
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary.exp
@@ -0,0 +1,186 @@
+# Expect script for ELF secondary symbol tests.
+# Copyright 2012
+# Free Software Foundation, Inc.
+#
+# This file is part of the GNU Binutils.
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
+# MA 02110-1301, USA.
+#
+
+# Exclude non-ELF targets.
+
+# The following tests require running the executable generated by ld,
+# or enough of a build environment to create a fully linked executable.
+# This is not commonly available when testing a cross-built linker.
+if ![isnative] {
+ return
+}
+
+if ![is_elf_format] {
+ return
+}
+
+# Check to see if the C compiler works
+if { [which $CC] == 0 } {
+ return
+}
+
+set build_tests {
+ {"Build secondary1.o"
+ "-r -nostdlib" ""
+ {secondary.c} {{readelf {-s} secondary.rd}} "secondary1.o"}
+ {"Build secondary1.so"
+ "-Wl,-z,nosecondary -shared" "-fPIC"
+ {secondary.c} {{readelf {--dyn-syms} secondary1.rd}} "secondary1.so"}
+ {"Build secondary2.so"
+ "-shared" "-fPIC"
+ {secondary.c} {{readelf {--dyn-syms} secondary2.rd}} "secondary2.so"}
+ {"Build libfoo.so"
+ "-shared" "-fPIC"
+ {secondary-foo.c} {} "libfoo.so"}
+ {"Build secondary-main with secondary.o"
+ "tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} {{readelf {--dyn-syms} secondary1.rd}} "secondary"}
+ {"Build library1.so"
+ "-shared" "-fPIC -DSHARED"
+ {library1.c} {} "library1.so"}
+ {"Build library2.so"
+ "-shared" "-fPIC -DSHARED"
+ {library2.c} {} "library2.so"}
+ {"Build library1.a"
+ "" ""
+ {library1.c} {} "library1.a"}
+ {"Build library2.a"
+ "" ""
+ {library2.c} {} "library2.a"}
+ {"Build secondary3a.o"
+ "" ""
+ {secondary3a.s} {} "secondary3a.a"}
+ {"Build secondary3"
+ "-nostdlib tmpdir/secondary3a.o" ""
+ {secondary3b.s} {{readelf {-s} secondary3.rd}} "secondary3"}
+ {"Build secondary4.so"
+ "-nostdlib -shared tmpdir/secondary3a.o" ""
+ {secondary4.s} {{readelf {--dyn-syms} secondary4.rd}} "secondary4.so"}
+ {"Build library5a.a"
+ "" ""
+ {library5a.c} {} "library5a.a"}
+ {"Build library5b.a"
+ "" ""
+ {library5b.c} {} "library5b.a"}
+ {"Build secondary5.a"
+ "" ""
+ {secondary5.c} {} "secondary5.a"}
+ {"Build library6a.a"
+ "" ""
+ {library6a.c} {} "library6a.a"}
+ {"Build library6b.a"
+ "" ""
+ {library6b.c} {} "library6b.a"}
+ {"Build library6c.a"
+ "" ""
+ {library6c.c} {} "library6c.a"}
+ {"Build secondary6.a"
+ "" ""
+ {secondary6.c} {} "secondary6.a"}
+ {"Build library7a.a"
+ "" ""
+ {library7a.c} {} "library7a.a"}
+ {"Build library7b.a"
+ "" ""
+ {library7b.c} {} "library7b.a"}
+ {"Build library7c.a"
+ "" ""
+ {library7c.c} {} "library7c.a"}
+ {"Build secondary7.a"
+ "" ""
+ {secondary7.c} {} "secondary7.a"}
+ {"Build library8a.so"
+ "-shared -Wl,--version-script=library8.map" "-fPIC"
+ {library8a.c} {{readelf {-s} library8a.rd}} "library8a.so"}
+ {"Build library8b.so"
+ "-shared -Wl,--version-script=library8.map" "-fPIC"
+ {library8b.c} {{readelf {-s} library8b.rd}} "library8b.so"}
+ {"Build library8c.a"
+ "" "-fPIC"
+ {library8c.c} {} "library8c.a"}
+ {"Build library8c.so"
+ "-shared -Wl,--version-script=library8.map tmpdir/library8c.o tmpdir/library8a.so tmpdir/library8b.so"
+ "-fPIC"
+ {dummy.c} {{readelf {-s} library8c.rd}} "library8c.so"}
+ {"Build secondary8a.so"
+ "-shared -Wl,--version-script=secondary8a.map" "-fPIC"
+ {secondary8a.c} {{readelf {-s} secondary8a.rd}} "secondary8a.so"}
+ {"Build secondary8b.a"
+ "" "-fPIC"
+ {secondary8b.c} {} "secondary8b.a"}
+ {"Build secondary8b.so"
+ "-shared -Wl,--start-group tmpdir/secondary8a.so tmpdir/secondary8b.o"
+ "-fPIC"
+ {dummy.c} {{readelf {-s} secondary8b.rd}} "secondary8b.so"}
+}
+
+run_cc_link_tests $build_tests
+
+set run_tests {
+ {"Run secondary-main with secondary.o"
+ "tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary1" "secondary1.out"}
+ {"Run secondary-main with secondary1.so"
+ "tmpdir/secondary1.so tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary2" "secondary1.out"}
+ {"Run secondary-main with secondary.o library1.o"
+ "tmpdir/secondary.o tmpdir/secondary.o tmpdir/library1.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary3" "library1.out"}
+ {"Run secondary-main with library1.o secondary.o"
+ "tmpdir/library1.o tmpdir/secondary.o tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary4" "library1.out"}
+ {"Run secondary-main with secondary.o library2.o"
+ "tmpdir/secondary.o tmpdir/library2.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary5" "library2.out"}
+ {"Run secondary-main with library2.o secondary.o"
+ "tmpdir/library2.o tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary6" "library2.out"}
+ {"Run secondary-main with secondary.o library1.so"
+ "tmpdir/secondary.o tmpdir/library1.so tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary7" "library3.out"}
+ {"Run secondary-main with library1.so secondary.o"
+ "tmpdir/library1.so tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary8" "library3.out"}
+ {"Run secondary-main with secondary.o library2.so"
+ "tmpdir/secondary.o tmpdir/library2.so tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary9" "library4.out"}
+ {"Run secondary-main with library2.so secondary.o"
+ "tmpdir/library2.so tmpdir/secondary.o tmpdir/libfoo.so" ""
+ {secondary-main.c} "secondary10" "library4.out"}
+ {"Run secondary5 with library5a.a library5b.a"
+ "tmpdir/secondary5.o tmpdir/library5a.a tmpdir/library5b.a" ""
+ {dummy.c} "secondary5a" "secondary5.out"}
+ {"Run secondary5 with -( library5a.a library5b.a -)"
+ "tmpdir/secondary5.o -\\( tmpdir/library5a.a tmpdir/library5b.a -\\)" ""
+ {dummy.c} "secondary5b" "secondary5.out"}
+ {"Run secondary5 with -( library5a.a library5b.a -) -( library5a.a library5b.a -)"
+ "tmpdir/secondary5.o -\\( tmpdir/library5a.a tmpdir/library5b.a -\\) -\\( tmpdir/library5a.a tmpdir/library5b.a -\\)" ""
+ {dummy.c} "secondary5c" "secondary5.out"}
+ {"Run secondary6 with -( library6a.a library6b.a library6c.a -)"
+ "tmpdir/secondary6.o -\\( tmpdir/library6a.a tmpdir/library6b.a tmpdir/library6c.a -\\)" ""
+ {dummy.c} "secondary6" "secondary6.out"}
+ {"Run secondary7 with -( library7a.a library7b.a library7c.a -)"
+ "tmpdir/secondary7.o -\\( tmpdir/library7a.a tmpdir/library7b.a tmpdir/library7c.a -\\)" ""
+ {dummy.c} "secondary7" "secondary7.out"}
+}
+
+run_ld_link_exec_tests [] $run_tests
diff --git a/ld/testsuite/ld-elf/secondary.rd b/ld/testsuite/ld-elf/secondary.rd
new file mode 100644
index 00000000000..9931c045b09
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary.rd
@@ -0,0 +1,5 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar
+#...
diff --git a/ld/testsuite/ld-elf/secondary1.out b/ld/testsuite/ld-elf/secondary1.out
new file mode 100644
index 00000000000..8d9378f95b4
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary1.out
@@ -0,0 +1 @@
+secondary bar
diff --git a/ld/testsuite/ld-elf/secondary1.rd b/ld/testsuite/ld-elf/secondary1.rd
new file mode 100644
index 00000000000..89d6d76d43e
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary1.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +WEAK +DEFAULT +[0-9]+ +_?bar
+#...
diff --git a/ld/testsuite/ld-elf/secondary2.rd b/ld/testsuite/ld-elf/secondary2.rd
new file mode 100644
index 00000000000..ff618a035ca
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary2.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9a-f]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar
+#...
diff --git a/ld/testsuite/ld-elf/secondary3.rd b/ld/testsuite/ld-elf/secondary3.rd
new file mode 100644
index 00000000000..562244a0294
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary3.rd
@@ -0,0 +1,6 @@
+Symbol table '\.symtab' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#failif
+#...
+ +[0-9]+: +0+ +0+ +[A-Z]+ +WEAK +DEFAULT +UND +_?foo
+#...
diff --git a/ld/testsuite/ld-elf/secondary3a.s b/ld/testsuite/ld-elf/secondary3a.s
new file mode 100644
index 00000000000..16a130043ef
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary3a.s
@@ -0,0 +1,4 @@
+ .section .text,"axG",%progbits,foo_group,comdat
+ .global bar
+bar:
+ .byte 0
diff --git a/ld/testsuite/ld-elf/secondary3b.s b/ld/testsuite/ld-elf/secondary3b.s
new file mode 100644
index 00000000000..cc6f37bd7e2
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary3b.s
@@ -0,0 +1,20 @@
+ .section .text,"axG",%progbits,foo_group,comdat
+ .secondary foo
+ .global bar
+foo:
+ .byte 0
+bar:
+ .byte 0
+ .data
+ .dc.a foo
+
+ .text
+ .global start /* Used by SH targets. */
+start:
+ .global _start
+_start:
+ .global __start
+__start:
+ .global main /* Used by HPPA targets. */
+main:
+ .dc.a bar
diff --git a/ld/testsuite/ld-elf/secondary4.rd b/ld/testsuite/ld-elf/secondary4.rd
new file mode 100644
index 00000000000..e84b1a6cb86
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary4.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +0+ +0+ +[A-Z]+ +WEAK +DEFAULT +UND +_?foo
+#...
diff --git a/ld/testsuite/ld-elf/secondary4.s b/ld/testsuite/ld-elf/secondary4.s
new file mode 100644
index 00000000000..a2acf21c573
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary4.s
@@ -0,0 +1,9 @@
+ .section .text,"axG",%progbits,foo_group,comdat
+ .secondary foo
+ .global bar
+foo:
+ .byte 0
+bar:
+ .byte 0
+ .data
+ .dc.a foo
diff --git a/ld/testsuite/ld-elf/secondary5.c b/ld/testsuite/ld-elf/secondary5.c
new file mode 100644
index 00000000000..a2b2f20695a
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary5.c
@@ -0,0 +1,10 @@
+extern void foo (void);
+extern void xxx (void);
+
+int
+main (void)
+{
+ foo ();
+ xxx ();
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/secondary5.out b/ld/testsuite/ld-elf/secondary5.out
new file mode 100644
index 00000000000..730c35dceb3
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary5.out
@@ -0,0 +1,3 @@
+foo
+secondary bar
+xxx
diff --git a/ld/testsuite/ld-elf/secondary6.c b/ld/testsuite/ld-elf/secondary6.c
new file mode 100644
index 00000000000..2a7e17b94b0
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary6.c
@@ -0,0 +1,11 @@
+#include <stdio.h>
+
+extern void xxx (void);
+
+int
+main (void)
+{
+ xxx ();
+ printf ("OK\n");
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/secondary6.out b/ld/testsuite/ld-elf/secondary6.out
new file mode 100644
index 00000000000..d86bac9de59
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary6.out
@@ -0,0 +1 @@
+OK
diff --git a/ld/testsuite/ld-elf/secondary7.c b/ld/testsuite/ld-elf/secondary7.c
new file mode 100644
index 00000000000..9a67352e95c
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary7.c
@@ -0,0 +1,13 @@
+#include <stdio.h>
+
+extern void abort (void);
+extern int xxx (void);
+
+int
+main (void)
+{
+ if (xxx () != 0)
+ abort ();
+ printf ("OK\n");
+ return 0;
+}
diff --git a/ld/testsuite/ld-elf/secondary7.out b/ld/testsuite/ld-elf/secondary7.out
new file mode 100644
index 00000000000..d86bac9de59
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary7.out
@@ -0,0 +1 @@
+OK
diff --git a/ld/testsuite/ld-elf/secondary8a.c b/ld/testsuite/ld-elf/secondary8a.c
new file mode 100644
index 00000000000..22b55aa4256
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary8a.c
@@ -0,0 +1,13 @@
+#if 1
+asm (".secondary __bar");
+asm (".secondary bar");
+#else
+asm (".weak __bar");
+asm (".weak bar");
+#endif
+
+void
+__bar (void)
+{
+}
+asm (".set bar, __bar");
diff --git a/ld/testsuite/ld-elf/secondary8a.map b/ld/testsuite/ld-elf/secondary8a.map
new file mode 100644
index 00000000000..29476406f7c
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary8a.map
@@ -0,0 +1,4 @@
+VERS_1 {
+ global: bar;
+ local: *;
+};
diff --git a/ld/testsuite/ld-elf/secondary8a.rd b/ld/testsuite/ld-elf/secondary8a.rd
new file mode 100644
index 00000000000..f52033c4dad
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary8a.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +[0-9a-f]+ +[0-9]+ +FUNC +SECOND +DEFAULT +[0-9]+ +_?bar@@VERS_1
+#...
diff --git a/ld/testsuite/ld-elf/secondary8b.c b/ld/testsuite/ld-elf/secondary8b.c
new file mode 100644
index 00000000000..22b55aa4256
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary8b.c
@@ -0,0 +1,13 @@
+#if 1
+asm (".secondary __bar");
+asm (".secondary bar");
+#else
+asm (".weak __bar");
+asm (".weak bar");
+#endif
+
+void
+__bar (void)
+{
+}
+asm (".set bar, __bar");
diff --git a/ld/testsuite/ld-elf/secondary8b.rd b/ld/testsuite/ld-elf/secondary8b.rd
new file mode 100644
index 00000000000..276c3ce72f5
--- /dev/null
+++ b/ld/testsuite/ld-elf/secondary8b.rd
@@ -0,0 +1,5 @@
+Symbol table '\.dynsym' contains [0-9]+ entries:
+ +Num: +Value +Size Type +Bind +Vis +Ndx Name
+#...
+ +[0-9]+: +0+ +0+ +FUNC +SECOND +DEFAULT +UND +_?bar@VERS_1 +\([0-9]+\)
+#...