From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from smtp-3.sys.kth.se (smtp-3.sys.kth.se [IPv6:2001:6b0:1:1300:250:56ff:fea6:2de2]) by sourceware.org (Postfix) with ESMTPS id A20B0385802D; Sun, 8 Aug 2021 15:20:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A20B0385802D Received: from smtp-3.sys.kth.se (localhost.localdomain [127.0.0.1]) by smtp-3.sys.kth.se (Postfix) with ESMTP id 8648B2D24; Sun, 8 Aug 2021 17:20:19 +0200 (CEST) X-Virus-Scanned: by amavisd-new at kth.se Received: from smtp-3.sys.kth.se ([127.0.0.1]) by smtp-3.sys.kth.se (smtp-3.sys.kth.se [127.0.0.1]) (amavisd-new, port 10024) with LMTP id Oxu1D7d43ilh; Sun, 8 Aug 2021 17:20:18 +0200 (CEST) Received: from exdb2.ug.kth.se (exdb2.ug.kth.se [192.168.32.57]) by smtp-3.sys.kth.se (Postfix) with ESMTPS id 5E66E2C68; Sun, 8 Aug 2021 17:20:18 +0200 (CEST) Received: from exdb6.ug.kth.se (192.168.32.61) by exdb2.ug.kth.se (192.168.32.57) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.858.15; Sun, 8 Aug 2021 17:20:18 +0200 Received: from exdb6.ug.kth.se ([192.168.32.61]) by exdb6.ug.kth.se ([192.168.32.61]) with mapi id 15.02.0858.015; Sun, 8 Aug 2021 17:20:18 +0200 From: Petter Tomner To: "gcc-patches@gcc.gnu.org" , Petter Tomner , "jit@gcc.gnu.org" Subject: [PATCH 2/3] jit: Add support for weak linkage Thread-Topic: [PATCH 2/3] jit: Add support for weak linkage Thread-Index: AQHXjGjl5RWU5eJ9bE2RP5PYuisVJw== Date: Sun, 8 Aug 2021 15:20:17 +0000 Message-ID: <440067e53767456ba3f8db1a20567d34@kth.se> References: <44423472d36e42f1a6e3612b704ba513@kth.se> In-Reply-To: <44423472d36e42f1a6e3612b704ba513@kth.se> Accept-Language: sv-SE, en-US Content-Language: sv-SE X-MS-Has-Attach: X-MS-TNEF-Correlator: x-originating-ip: [192.168.32.250] Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 X-Spam-Status: No, score=-12.6 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, SPF_HELO_PASS, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.4 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on server2.sourceware.org X-BeenThere: jit@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Jit mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 08 Aug 2021 15:20:23 -0000 This patch has a test case for weak linkage as well as modification of help= er functions. Essentially it produces two object files, one with weak and o= ne with normal symbols, and a main which prints the values of those two sym= bols and a cehck to ensure that the normal symbols' values are printed. 2021-08-08 Petter Tomner 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/j= it.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 =20 +/* 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[] =3D { verify_code_version}, {"volatile", create_code_volatile, - verify_code_volatile} + verify_code_volatile}, + {"weak_symbols", + create_code_weak_symbols, + verify_code_weak_symbols} }; =20 const int num_testcases =3D (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 *ar= gv0) free (reproducer_name); } =20 +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 */ =20 /* 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 } { } } =20 +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] =3D=3D 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} } =20 +# Compile 'sources' and link in 'objects' and execute the program=20 +# 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] =3D=3D 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/testsui= te/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[] =3D {1}; + + weaksymtest_foobar.o: =20 + int weaksymtest_foo() {return 2;} + int weaksymtest_bar[] =3D {2}; + + and then link them together and verify that the weak symbol is actually= =20 + weak and not the one used after linking. + + Since multiple outfiles are needed this test uses TEST_COMPILING_TO_FIL= E + in a slightly different way then the other tests. It provides its own + test_jit() via TEST_PROVIDES_TEST_JIT. + =20 + This test is dependent on verify-weak-linkage.c which is a main functio= n + with declarations of foo and bar and that outputs foo() and bar[0] to=20 + stdout. */ + +#include +#include + +#include "libgccjit.h" + +/* When included in all-non-failing-tests.h with COMBINED_TEST defined=20 + 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 =3D gcc_jit_result_get_code (result, "weaksymtest_foo"); + int *bar =3D 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 =3D concat_strings (argv0, ".weak"); + argv0_normal =3D concat_strings (argv0, ".normal"); + + unlink ("weaksymtest_foobar_weak.o"); + unlink ("weaksymtest_foobar.o"); + =20 + ctxt_weak =3D gcc_jit_context_acquire (); + ctxt_normal =3D gcc_jit_context_acquire (); + if (!ctxt_normal || !ctxt_weak) + { + fail ("gcc_jit_context_acquire failed"); + return; + } + =20 + logfile_weak =3D set_up_logging (ctxt_weak, argv0_weak); + logfile_normal =3D set_up_logging (ctxt_normal, argv0_normal); + + set_options (ctxt_normal, argv0_normal); + set_options (ctxt_weak, argv0_weak); + + free (argv0_weak); argv0_weak =3D 0; + free (argv0_normal); argv0_normal =3D 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=20 + 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=20 + to check manually that the symbols are weak with=20 + 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 =3D 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)=20 + { + fn_kind =3D GCC_JIT_FUNCTION_EXPORTED_WEAK; + var_kind =3D GCC_JIT_GLOBAL_EXPORTED_WEAK; + value =3D 1; + }=20 + else=20 + { + fn_kind =3D GCC_JIT_FUNCTION_EXPORTED; + var_kind =3D GCC_JIT_GLOBAL_EXPORTED; + value =3D 2; + } + + /* int __attribute__((weak)) foo() { return 1;} + int foo() { return 2;} */ + gcc_jit_type *int_type =3D=20 + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_function *foo =3D=20 + gcc_jit_context_new_function (ctxt, 0, fn_kind, int_type,=20 + "weaksymtest_foo", 0,0,0); + gcc_jit_block *block1 =3D + gcc_jit_function_new_block (foo, "block1"); + gcc_jit_block_end_with_return (block1, 0,=20 + gcc_jit_context_new_rvalue_from_int (ctxt, int_type, value)); + =20 + /* int __attribute__((weak)) bar[] =3D {1}; + int bar[] =3D {2}; */ + gcc_jit_lvalue *bar =3D gcc_jit_context_new_global (ctxt, 0, var_kind,=20 + gcc_jit_context_new_array_type (ctxt, 0, int_type, 1), "weaksymtest_ba= r"); + =20 + arr[0] =3D 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 ob= ject files + and checks that the stdout of the resulting executable matches "2\n2\n"= which=20 + 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=20 + of bar[0] and foo() and should print 2\n2\n if the + weak symbols are not linked in. */ + +#include + +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; +} + --=20 2.20.1