aboutsummaryrefslogtreecommitdiff
path: root/ld/testsuite/ld-plugin
diff options
context:
space:
mode:
authorH.J. Lu <hjl.tools@gmail.com>2015-02-03 09:03:23 -0800
committerH.J. Lu <hjl.tools@gmail.com>2015-02-03 09:03:23 -0800
commit60f79275127603876d94da4bf4e3f6212903b407 (patch)
tree7aef6f3ba041e6588c0c354e7491bafff6ba7da8 /ld/testsuite/ld-plugin
parent9910b1c8f3b0821944303fbcb4ef4c8872cf4e08 (diff)
Mark the plugin symbol undefined
LTO may optimize out a plugin symbol, which is also referenced by a non-IR file. When that happens, we should mark the plugin symbol undefined. It isn't the problem since LTO already determined the symbols in the non-IR file aren't used. bfd/ PR ld/12365 PR ld/14272 * elflink.c (_bfd_elf_fix_symbol_flags): Mark the plugin symbol undefined if it is referenced from a non-IR file. ld/testsuite/ PR ld/12365 * ld-plugin/pr12365a.c: New file. * ld-plugin/pr12365b.c: Likewise. * ld-plugin/pr12365c.c: Likewise. * ld-plugin/lto.exp (lto_link_tests): Prepare for the PR ld/12365 test. Run the PR ld/12365 test.
Diffstat (limited to 'ld/testsuite/ld-plugin')
-rw-r--r--ld/testsuite/ld-plugin/lto.exp10
-rw-r--r--ld/testsuite/ld-plugin/pr12365a.c25
-rw-r--r--ld/testsuite/ld-plugin/pr12365b.c47
-rw-r--r--ld/testsuite/ld-plugin/pr12365c.c79
4 files changed, 161 insertions, 0 deletions
diff --git a/ld/testsuite/ld-plugin/lto.exp b/ld/testsuite/ld-plugin/lto.exp
index f0643cc545..400e683ec7 100644
--- a/ld/testsuite/ld-plugin/lto.exp
+++ b/ld/testsuite/ld-plugin/lto.exp
@@ -88,6 +88,9 @@ set lto_link_tests [list \
[list "LTO 6" \
"-O2 -flto -fuse-linker-plugin" "" \
{lto-6.c} {} "lto-6.exe" "c"] \
+ [list "Compile PR ld/12365" \
+ "" "-flto -O2 $lto_fat" \
+ {pr12365a.c pr12365b.c pr12365c.c} {} ""] \
[list "Compile 9" \
"" "-O2 -finline -flto" \
{lto-9.cc} {} "" "c++"] \
@@ -380,6 +383,13 @@ if {![string match "" $catch_output]} {
if { [at_least_gcc_version 4 7] } {
# Check expected LTO linker errors.
+ set testname "PR ld/12365"
+ set exec_output [run_host_cmd "$CC" "-O2 -flto -fuse-linker-plugin tmpdir/pr12365a.o tmpdir/pr12365b.o tmpdir/pr12365c.o"]
+ if { [ regexp "undefined reference to `my_bcopy'" $exec_output ] } {
+ pass $testname
+ } {
+ fail $testname
+ }
set testname "PR ld/12942 (3)"
set exec_output [run_host_cmd "$CXX" "-O2 -flto -fuse-linker-plugin tmpdir/pr12942b.o tmpdir/pr12942a.o"]
if { [ regexp "undefined reference to `link_error\\(\\)'" $exec_output ] } {
diff --git a/ld/testsuite/ld-plugin/pr12365a.c b/ld/testsuite/ld-plugin/pr12365a.c
new file mode 100644
index 0000000000..a9bb6c6b89
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365a.c
@@ -0,0 +1,25 @@
+extern void abort(void);
+extern void main_test (void);
+extern void abort (void);
+int inside_main;
+
+int
+main ()
+{
+ inside_main = 1;
+ main_test ();
+ inside_main = 0;
+ return 0;
+}
+
+/* When optimizing, all the constant cases should have been
+ constant folded, so no calls to link_error should remain.
+ In any case, link_error should not be called. */
+
+#ifndef __OPTIMIZE__
+void
+link_error (void)
+{
+ abort ();
+}
+#endif
diff --git a/ld/testsuite/ld-plugin/pr12365b.c b/ld/testsuite/ld-plugin/pr12365b.c
new file mode 100644
index 0000000000..a5a80e0817
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365b.c
@@ -0,0 +1,47 @@
+#define ASMNAME(cname) ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+#define ASMNAME2(prefix, cname) STRING (prefix) cname
+#define STRING(x) #x
+
+typedef __SIZE_TYPE__ size_t;
+extern void abort (void);
+extern void *memcpy (void *, const void *, size_t)
+ __asm (ASMNAME ("my_memcpy"));
+extern void bcopy (const void *, void *, size_t)
+ __asm (ASMNAME ("my_bcopy"));
+extern void *memset (void *, int, size_t)
+ __asm (ASMNAME ("my_memset"));
+extern void bzero (void *, size_t)
+ __asm (ASMNAME ("my_bzero"));
+extern int memcmp (const void *, const void *, size_t);
+
+struct A { char c[32]; } a = { "foobar" };
+char x[64] = "foobar", y[64];
+int i = 39, j = 6, k = 4;
+
+extern int inside_main;
+
+void
+main_test (void)
+{
+ struct A b = a;
+ struct A c = { { 'x' } };
+
+ inside_main = 1;
+
+ if (memcmp (b.c, x, 32) || c.c[0] != 'x' || memcmp (c.c + 1, x + 32, 31))
+ abort ();
+ if (__builtin_memcpy (y, x, i) != y || memcmp (x, y, 64))
+ abort ();
+ if (memcpy (y + 6, x, j) != y + 6
+ || memcmp (x, y, 6) || memcmp (x, y + 6, 58))
+ abort ();
+ if (__builtin_memset (y + 2, 'X', k) != y + 2
+ || memcmp (y, "foXXXXfoobar", 13))
+ abort ();
+ bcopy (y + 1, y + 2, 6);
+ if (memcmp (y, "fooXXXXfobar", 13))
+ abort ();
+ __builtin_bzero (y + 4, 2);
+ if (memcmp (y, "fooX\0\0Xfobar", 13))
+ abort ();
+}
diff --git a/ld/testsuite/ld-plugin/pr12365c.c b/ld/testsuite/ld-plugin/pr12365c.c
new file mode 100644
index 0000000000..2edd0ffa74
--- /dev/null
+++ b/ld/testsuite/ld-plugin/pr12365c.c
@@ -0,0 +1,79 @@
+extern void abort (void);
+extern int inside_main;
+typedef __SIZE_TYPE__ size_t;
+
+#define TEST_ABORT if (inside_main) abort()
+
+void *
+my_memcpy (void *d, const void *s, size_t n)
+{
+ char *dst = (char *) d;
+ const char *src = (const char *) s;
+ while (n--)
+ *dst++ = *src++;
+ return (char *) d;
+}
+
+void
+my_bcopy (const void *s, void *d, size_t n)
+{
+ char *dst = (char *) d;
+ const char *src = (const char *) s;
+ if (src >= dst)
+ while (n--)
+ *dst++ = *src++;
+ else
+ {
+ dst += n;
+ src += n;
+ while (n--)
+ *--dst = *--src;
+ }
+}
+
+void *
+my_memset (void *d, int c, size_t n)
+{
+ char *dst = (char *) d;
+ while (n--)
+ *dst++ = c;
+ return (char *) d;
+}
+
+void
+my_bzero (void *d, size_t n)
+{
+ char *dst = (char *) d;
+ while (n--)
+ *dst++ = '\0';
+}
+
+void *
+memcpy (void *d, const void *s, size_t n)
+{
+ void *result = my_memcpy (d, s, n);
+ TEST_ABORT;
+ return result;
+}
+
+void
+bcopy (const void *s, void *d, size_t n)
+{
+ my_bcopy (s, d, n);
+ TEST_ABORT;
+}
+
+void *
+memset (void *d, int c, size_t n)
+{
+ void *result = my_memset (d, c, n);
+ TEST_ABORT;
+ return result;
+}
+
+void
+bzero (void *d, size_t n)
+{
+ my_bzero (d, n);
+ TEST_ABORT;
+}