From: Petter Tomner <tomner@kth.se>
To: "gcc-patches@gcc.gnu.org" <gcc-patches@gcc.gnu.org>,
Petter Tomner <tomner@kth.se>,
"jit@gcc.gnu.org" <jit@gcc.gnu.org>
Subject: [PATCH 2/3] jit: Add support for weak linkage
Date: Sun, 8 Aug 2021 15:20:17 +0000 [thread overview]
Message-ID: <440067e53767456ba3f8db1a20567d34@kth.se> (raw)
In-Reply-To: <44423472d36e42f1a6e3612b704ba513@kth.se>
This patch has a test case for weak linkage as well as modification of helper functions. Essentially it produces two object files, one with weak and one with normal symbols, and a main which prints the values of those two symbols and a cehck to ensure that the normal symbols' values are printed.
2021-08-08 Petter Tomner <tomner@kth.se>
gcc/testsuite/
* all-non-failing-tests.h : "weak_symbols" added to test list
* harness.h : Macro flag to be able to provide own test_jit()
* jit.exp : Helper functions with support for 2+ outfiles
* test-compile-weak-symbols.c : New test case
* verify-weak-linkage.c : main function for linking to obj. files.
---
gcc/testsuite/jit.dg/all-non-failing-tests.h | 12 +-
gcc/testsuite/jit.dg/harness.h | 5 +
gcc/testsuite/jit.dg/jit.exp | 69 ++++++
.../jit.dg/test-compile-weak-symbols.c | 207 ++++++++++++++++++
gcc/testsuite/jit.dg/verify-weak-linkage.c | 21 ++
5 files changed, 313 insertions(+), 1 deletion(-)
create mode 100644 gcc/testsuite/jit.dg/test-compile-weak-symbols.c
create mode 100644 gcc/testsuite/jit.dg/verify-weak-linkage.c
diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h
index 84ef54a0386..4da34905a3d 100644
--- a/gcc/testsuite/jit.dg/all-non-failing-tests.h
+++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h
@@ -105,6 +105,13 @@
#undef create_code
#undef verify_code
+/* test-compile-weak-symbols.c */
+#define create_code create_code_weak_symbols
+#define verify_code verify_code_weak_symbols
+#include "test-compile-weak-symbols.c"
+#undef create_code
+#undef verify_code
+
/* test-compound-assignment.c */
#define create_code create_code_compound_assignment
#define verify_code verify_code_compound_assignment
@@ -454,7 +461,10 @@ const struct testcase testcases[] = {
verify_code_version},
{"volatile",
create_code_volatile,
- verify_code_volatile}
+ verify_code_volatile},
+ {"weak_symbols",
+ create_code_weak_symbols,
+ verify_code_weak_symbols}
};
const int num_testcases = (sizeof (testcases) / sizeof (testcases[0]));
diff --git a/gcc/testsuite/jit.dg/harness.h b/gcc/testsuite/jit.dg/harness.h
index 6b59fb57aae..84c248303f4 100644
--- a/gcc/testsuite/jit.dg/harness.h
+++ b/gcc/testsuite/jit.dg/harness.h
@@ -331,6 +331,10 @@ dump_reproducer (gcc_jit_context *ctxt, const char *argv0)
free (reproducer_name);
}
+static void
+test_jit (const char *argv0, void *user_data);
+
+#ifndef TEST_PROVIDES_TEST_JIT
/* Run one iteration of the test. */
static void
test_jit (const char *argv0, void *user_data)
@@ -383,6 +387,7 @@ test_jit (const char *argv0, void *user_data)
if (logfile)
fclose (logfile);
}
+#endif /* #ifndef TEST_PROVIDES_TEST_JIT */
#endif /* #ifndef TEST_ESCHEWS_TEST_JIT */
/* We want to prefix all unit test results with the test, but dejagnu.exp's
diff --git a/gcc/testsuite/jit.dg/jit.exp b/gcc/testsuite/jit.dg/jit.exp
index 9af87f9c6ad..f26970a41e6 100644
--- a/gcc/testsuite/jit.dg/jit.exp
+++ b/gcc/testsuite/jit.dg/jit.exp
@@ -692,6 +692,19 @@ proc jit-verify-output-file-was-created { args } {
}
}
+proc jit-verify-output-files-were-created { args } {
+ verbose "jit-verify-output-files-were-created: $args"
+
+ foreach output_filename $args {
+ # Verify that the expected files was written out
+ if { [file exists $output_filename] == 1} {
+ pass "$output_filename exists"
+ } else {
+ fail "$output_filename does not exist"
+ }
+ }
+}
+
# Verify that the given file exists, and is executable.
# Attempt to execute it, and verify that its stdout matches
# the given regex.
@@ -840,6 +853,62 @@ proc jit-verify-object { args } {
jit-run-executable ${executable_from_obj} ${dg-output-text}
}
+# Compile 'sources' and link in 'objects' and execute the program
+# and check that its output matches 'expected_output'.
+#
+# The path to the JIT test source folder is prepended to each
+# word in 'source'.
+#
+# For use with test-compile-weak-symbols.c testcase.
+proc jit-verify-sources-objects { expected_output sources objects } {
+ global srcdir
+ global subdir
+
+ verbose "jit-verify-objects: $expected_output $sources $objects"
+ set dg-output-text $expected_output
+
+ # prepend the path to the folder with the JIT tests
+ # to each source
+ set rel_path "$srcdir/$subdir/"
+ set srcs [lmap i $sources { string cat $rel_path $i }]
+ verbose "sources full path: ${srcs}"
+
+ upvar 2 name name
+ verbose "name: $name"
+
+ upvar 2 prog prog
+ verbose "prog: $prog"
+
+ # Name the linked executable as the first source
+ # with ".exe" appended.
+ set executable_from_obj [lindex $sources 0].exe
+ verbose " executable_from_obj: ${executable_from_obj}"
+
+ # Invoke the driver to link the .o file to the .exe
+ set comp_output [gcc_target_compile \
+ "${srcs} ${objects}" \
+ ${executable_from_obj} \
+ "executable" \
+ "{}"]
+ if ![jit_check_compile \
+ "$name" \
+ "link of ${executable_from_obj}" \
+ ${executable_from_obj} \
+ $comp_output] then {
+ return
+ }
+
+ # Verify that the executable was created.
+ if { [file exists $executable_from_obj] == 1} {
+ pass "$executable_from_obj exists"
+ } else {
+ fail "$executable_from_obj does not exist"
+ }
+
+ # Run it and verify that the output matches the regex.
+ jit-run-executable ${executable_from_obj} ${dg-output-text}
+}
+
# Assuming that a .so file has been written out named
# OUTPUT_FILENAME, build a test executable to use it,
# and try to run the result.
diff --git a/gcc/testsuite/jit.dg/test-compile-weak-symbols.c b/gcc/testsuite/jit.dg/test-compile-weak-symbols.c
new file mode 100644
index 00000000000..5a746850341
--- /dev/null
+++ b/gcc/testsuite/jit.dg/test-compile-weak-symbols.c
@@ -0,0 +1,207 @@
+/* Essentially the goal of the test is to create a two object files:
+
+ weaksymtest_foobar_weak.o:
+ int __attribute__((weak)) weaksymtest_foo() {return 1;}
+ int __attribute__((weak)) weaksymtest_bar[] = {1};
+
+ weaksymtest_foobar.o:
+ int weaksymtest_foo() {return 2;}
+ int weaksymtest_bar[] = {2};
+
+ and then link them together and verify that the weak symbol is actually
+ weak and not the one used after linking.
+
+ Since multiple outfiles are needed this test uses TEST_COMPILING_TO_FILE
+ in a slightly different way then the other tests. It provides its own
+ test_jit() via TEST_PROVIDES_TEST_JIT.
+
+ This test is dependent on verify-weak-linkage.c which is a main function
+ with declarations of foo and bar and that outputs foo() and bar[0] to
+ stdout. */
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "libgccjit.h"
+
+/* When included in all-non-failing-tests.h with COMBINED_TEST defined
+ this testfile does not produce any output files. */
+#ifndef COMBINED_TEST
+#define TEST_COMPILING_TO_FILE
+#define TEST_PROVIDES_TEST_JIT
+#include "harness.h"
+#undef TEST_PROVIDES_TEST_JIT
+#else
+#include "harness.h"
+#endif
+
+extern void
+create_code_weak_or_normal (gcc_jit_context *ctxt, int create_weak);
+
+typedef int (*fooptr)(void);
+
+void
+verify_code (gcc_jit_context *ctxt, gcc_jit_result *result)
+{
+ (void) ctxt; /* Not used */
+
+ fooptr foo = gcc_jit_result_get_code (result, "weaksymtest_foo");
+ int *bar = gcc_jit_result_get_global (result, "weaksymtest_bar");
+
+ /* Just do a simple test accessing the weak symbols from the
+ JIT context */
+ CHECK_VALUE (*bar, 1);
+ CHECK_VALUE (foo(), 1);
+}
+
+/* Do not provide test_jit() when included in all-non-failing-test.h */
+#ifndef COMBINED_TEST
+/* Runs one iteration of the test. */
+static void
+test_jit (const char *argv0, void *user_data)
+{
+ gcc_jit_context *ctxt_normal, *ctxt_weak;
+ FILE *logfile_normal, *logfile_weak;
+ char *argv0_weak, *argv0_normal;
+
+ (void) user_data; /* Not used */
+
+ argv0_weak = concat_strings (argv0, ".weak");
+ argv0_normal = concat_strings (argv0, ".normal");
+
+ unlink ("weaksymtest_foobar_weak.o");
+ unlink ("weaksymtest_foobar.o");
+
+ ctxt_weak = gcc_jit_context_acquire ();
+ ctxt_normal = gcc_jit_context_acquire ();
+ if (!ctxt_normal || !ctxt_weak)
+ {
+ fail ("gcc_jit_context_acquire failed");
+ return;
+ }
+
+ logfile_weak = set_up_logging (ctxt_weak, argv0_weak);
+ logfile_normal = set_up_logging (ctxt_normal, argv0_normal);
+
+ set_options (ctxt_normal, argv0_normal);
+ set_options (ctxt_weak, argv0_weak);
+
+ free (argv0_weak); argv0_weak = 0;
+ free (argv0_normal); argv0_normal = 0;
+
+ create_code_weak_or_normal (ctxt_normal, 0);
+ create_code_weak_or_normal (ctxt_weak, 1);
+
+ /* Note that argv0 is used instead of argv0_weak since
+ jit-dg-test expects a certain name of the dumpfile. */
+ dump_reproducer (ctxt_weak, argv0);
+
+ gcc_jit_context_compile_to_file (ctxt_normal,
+ GCC_JIT_OUTPUT_KIND_OBJECT_FILE,
+ "weaksymtest_foobar_n.o");
+ gcc_jit_context_compile_to_file (ctxt_weak,
+ GCC_JIT_OUTPUT_KIND_OBJECT_FILE,
+ "weaksymtest_foobar_w.o");
+
+ /* ld treats weak symbols in shared libraries like
+ normal symbols unless env.var. LD_DYNAMIC_WEAK is set,
+ so dynamic libraries are a bit awkward to test in
+ a unit test like we do here. However it is easy
+ to check manually that the symbols are weak with
+ objdump etc. */
+#if 0
+ unlink ("weaksymtest_foobar_weak.so");
+ unlink ("weaksymtest_foobar.so");
+ gcc_jit_context_compile_to_file (ctxt_weak,
+ GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY,
+ "libweaksymtest_foobar_w.so");
+ gcc_jit_context_compile_to_file (ctxt_normal,
+ GCC_JIT_OUTPUT_KIND_DYNAMIC_LIBRARY,
+ "libweaksymtest_foobar_n.so");
+#endif
+
+ /* For checking wether the c-like dump looks ok */
+#if 0
+ unlink("libweaksymtest_foobar_w.c");
+ gcc_jit_context_dump_to_file (ctxt_weak, "libweaksymtest_foobar_w.c", 0);
+#endif
+
+ CHECK_NO_ERRORS (ctxt_normal);
+ CHECK_NO_ERRORS (ctxt_weak);
+
+ gcc_jit_result *result_weak = gcc_jit_context_compile (ctxt_weak);
+ CHECK_NON_NULL (result_weak);
+ /* Just does some simple access and value check of the weak symbols */
+ CHECK_NO_ERRORS (ctxt_weak);
+ verify_code (ctxt_weak, result_weak);
+
+ gcc_jit_result_release (result_weak);
+
+ gcc_jit_context_release (ctxt_normal);
+ gcc_jit_context_release (ctxt_weak);
+
+ if (logfile_normal)
+ fclose (logfile_normal);
+ if (logfile_weak)
+ fclose (logfile_weak);
+}
+#endif /* #ifndef COMBINED_TEST */
+
+extern void
+create_code_weak_or_normal (gcc_jit_context *ctxt, int create_weak)
+{
+ enum gcc_jit_function_kind fn_kind;
+ enum gcc_jit_global_kind var_kind;
+ int value;
+ int arr[1];
+
+ if (create_weak)
+ {
+ fn_kind = GCC_JIT_FUNCTION_EXPORTED_WEAK;
+ var_kind = GCC_JIT_GLOBAL_EXPORTED_WEAK;
+ value = 1;
+ }
+ else
+ {
+ fn_kind = GCC_JIT_FUNCTION_EXPORTED;
+ var_kind = GCC_JIT_GLOBAL_EXPORTED;
+ value = 2;
+ }
+
+ /* int __attribute__((weak)) foo() { return 1;}
+ int foo() { return 2;} */
+ gcc_jit_type *int_type =
+ gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT);
+ gcc_jit_function *foo =
+ gcc_jit_context_new_function (ctxt, 0, fn_kind, int_type,
+ "weaksymtest_foo", 0,0,0);
+ gcc_jit_block *block1 =
+ gcc_jit_function_new_block (foo, "block1");
+ gcc_jit_block_end_with_return (block1, 0,
+ gcc_jit_context_new_rvalue_from_int (ctxt, int_type, value));
+
+ /* int __attribute__((weak)) bar[] = {1};
+ int bar[] = {2}; */
+ gcc_jit_lvalue *bar = gcc_jit_context_new_global (ctxt, 0, var_kind,
+ gcc_jit_context_new_array_type (ctxt, 0, int_type, 1), "weaksymtest_bar");
+
+ arr[0] = value;
+ gcc_jit_global_set_initializer (bar, (const void *)arr, sizeof(int));
+}
+
+/* This function is used in all-non-failing-test.h and just creates the
+ weak context */
+void
+create_code (gcc_jit_context *ctxt, void *user_data)
+{
+ (void) user_data;
+ create_code_weak_or_normal (ctxt, 1);
+}
+
+/* { dg-final { jit-verify-output-files-were-created "weaksymtest_foobar_w.o" "weaksymtest_foobar_n.o"} } */
+
+/* jit-verify-sources-objects compiles "verify-weak-linkage.c" with the object files
+ and checks that the stdout of the resulting executable matches "2\n2\n" which
+ indicates that the weak symbols are not used. */
+
+/* { dg-final { jit-verify-sources-objects "2\\n2\\n" "verify-weak-linkage.c" "weaksymtest_foobar_w.o weaksymtest_foobar_n.o"} } */
diff --git a/gcc/testsuite/jit.dg/verify-weak-linkage.c b/gcc/testsuite/jit.dg/verify-weak-linkage.c
new file mode 100644
index 00000000000..c3ac1b9a50d
--- /dev/null
+++ b/gcc/testsuite/jit.dg/verify-weak-linkage.c
@@ -0,0 +1,21 @@
+/* For use with jit-verify-sources-objects
+ used by test-compile-weak-symbols.c
+
+ This file is linked to two object files . One with
+ weak symbols, one with normal. It prints the value
+ of bar[0] and foo() and should print 2\n2\n if the
+ weak symbols are not linked in. */
+
+#include <stdio.h>
+
+extern int weaksymtest_bar[1];
+int weaksymtest_foo();
+
+int
+main (int argc, char **argv)
+{
+ printf ("%d\n", weaksymtest_foo());
+ printf ("%d\n", weaksymtest_bar[0]);
+ return 0;
+}
+
--
2.20.1
next prev parent reply other threads:[~2021-08-08 15:20 UTC|newest]
Thread overview: 4+ messages / expand[flat|nested] mbox.gz Atom feed top
2021-08-08 15:07 [PATCH 0/3] " Petter Tomner
2021-08-08 15:18 ` [PATCH 1/3] " Petter Tomner
2021-08-08 15:20 ` Petter Tomner [this message]
2021-08-08 15:21 ` [PATCH 3/3] " Petter Tomner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=440067e53767456ba3f8db1a20567d34@kth.se \
--to=tomner@kth.se \
--cc=gcc-patches@gcc.gnu.org \
--cc=jit@gcc.gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).