From patchwork Sun Aug 8 15:20:17 2021 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Petter Tomner X-Patchwork-Id: 1514808 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=XtZyAWbu; dkim-atps=neutral Received: from sourceware.org (ip-8-43-85-97.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4GjNFw6F25z9sX1 for ; Mon, 9 Aug 2021 01:20:52 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 64E7B385E454 for ; Sun, 8 Aug 2021 15:20:50 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 64E7B385E454 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1628436050; bh=rlXRjez+CiaYDFswWZTKXc+X4rIWNkN/zgcc53QQUco=; h=To:Subject:Date:References:In-Reply-To:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To: From; b=XtZyAWbuW5Vu0bgVY7ItSLSb4txwympgEluZcdA3pdzpElsxi60sUSX0A9wBGjNGh yQVXRhTr9+8+aPhyUcoA1P9NtrnPkc3kidUwRqPvEYGAQyIAXqfab/MmWO6S5vumr9 n3oGOfdfz0KNF0+UWsloU0JzlBdOz9KBkHWNFZYg= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org 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 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] 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: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: Petter Tomner via Gcc-patches From: Petter Tomner Reply-To: Petter Tomner Errors-To: gcc-patches-bounces+incoming=patchwork.ozlabs.org@gcc.gnu.org Sender: "Gcc-patches" 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 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 +#include + +#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 + +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; +} +