From patchwork Tue Feb 24 20:02:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 5269 Received: (qmail 69731 invoked by alias); 24 Feb 2015 20:02:49 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 69717 invoked by uid 89); 24 Feb 2015 20:02:48 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.1 required=5.0 tests=AWL, BAYES_00, KAM_STOCKGEN, SPF_HELO_PASS, T_RP_MATCHES_RCVD autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 24 Feb 2015 20:02:47 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (8.14.4/8.14.4) with ESMTP id t1OK2kLZ020838 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=FAIL) for ; Tue, 24 Feb 2015 15:02:46 -0500 Received: from host1.jankratochvil.net ([10.40.204.17]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t1OK2fSs003681 (version=TLSv1/SSLv3 cipher=AES256-SHA bits=256 verify=NO); Tue, 24 Feb 2015 15:02:44 -0500 Date: Tue, 24 Feb 2015 21:02:37 +0100 From: Jan Kratochvil To: gdb-patches@sourceware.org Cc: Phil Muldoon Subject: [patchv2] compile: Fix GNU-IFUNC funcs called from injected code Message-ID: <20150224200237.GA1746@host1.jankratochvil.net> References: <20150224190720.GA32497@host1.jankratochvil.net> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: <20150224190720.GA32497@host1.jankratochvil.net> User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Testcase cosmetic update. gdb/ChangeLog 2015-02-24 Jan Kratochvil * compile/compile-c-symbols.c (convert_one_symbol, convert_symbol_bmsym) (gcc_symbol_address): Call gnu_ifunc_resolve_addr. gdb/testsuite/ChangeLog 2015-02-24 Jan Kratochvil * gdb.compile/compile-ifunc.c: New file. * gdb.compile/compile-ifunc.exp: New file. diff --git a/gdb/compile/compile-c-symbols.c b/gdb/compile/compile-c-symbols.c index 6562f05..ba6a229 100644 --- a/gdb/compile/compile-c-symbols.c +++ b/gdb/compile/compile-c-symbols.c @@ -187,6 +187,8 @@ convert_one_symbol (struct compile_c_instance *context, case LOC_BLOCK: kind = GCC_C_SYMBOL_FUNCTION; addr = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + if (is_global && TYPE_GNU_IFUNC (SYMBOL_TYPE (sym))) + addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr); break; case LOC_CONST: @@ -365,6 +367,8 @@ convert_symbol_bmsym (struct compile_c_instance *context, gcc_decl decl; CORE_ADDR addr; + addr = MSYMBOL_VALUE_ADDRESS (objfile, msym); + /* Conversion copied from write_exp_msymbol. */ switch (MSYMBOL_TYPE (msym)) { @@ -376,8 +380,11 @@ convert_symbol_bmsym (struct compile_c_instance *context, break; case mst_text_gnu_ifunc: - type = objfile_type (objfile)->nodebug_text_gnu_ifunc_symbol; + // nodebug_text_gnu_ifunc_symbol would cause: + // function return type cannot be function + type = objfile_type (objfile)->nodebug_text_symbol; kind = GCC_C_SYMBOL_FUNCTION; + addr = gnu_ifunc_resolve_addr (target_gdbarch (), addr); break; case mst_data: @@ -400,7 +407,6 @@ convert_symbol_bmsym (struct compile_c_instance *context, } sym_type = convert_type (context, type); - addr = MSYMBOL_VALUE_ADDRESS (objfile, msym); decl = C_CTX (context)->c_ops->build_decl (C_CTX (context), MSYMBOL_NATURAL_NAME (msym), kind, sym_type, NULL, addr, @@ -497,6 +503,8 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context, "gcc_symbol_address \"%s\": full symbol\n", identifier); result = BLOCK_START (SYMBOL_BLOCK_VALUE (sym)); + if (TYPE_GNU_IFUNC (SYMBOL_TYPE (sym))) + result = gnu_ifunc_resolve_addr (target_gdbarch (), result); found = 1; } else @@ -512,6 +520,8 @@ gcc_symbol_address (void *datum, struct gcc_c_context *gcc_context, "symbol\n", identifier); result = BMSYMBOL_VALUE_ADDRESS (msym); + if (MSYMBOL_TYPE (msym.minsym) == mst_text_gnu_ifunc) + result = gnu_ifunc_resolve_addr (target_gdbarch (), result); found = 1; } } diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.c b/gdb/testsuite/gdb.compile/compile-ifunc.c new file mode 100644 index 0000000..e5cee77 --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-ifunc.c @@ -0,0 +1,46 @@ +/* This testcase is part of GDB, the GNU debugger. + + Copyright 2015 Free Software Foundation, Inc. + + 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, see . */ + +#include + +typedef int (*final_t) (int arg); + +int +final (int arg) +{ + return arg + 1; +} + +asm (".type gnu_ifunc, %gnu_indirect_function"); + +final_t +gnu_ifunc (void) +{ + return final; +} + +extern int gnu_ifunc_alias (int arg) __attribute__ ((alias ("gnu_ifunc"))); + +static int resultvar; + +int +main (void) +{ + if (gnu_ifunc_alias (10) != 11) + abort (); + return resultvar; +} diff --git a/gdb/testsuite/gdb.compile/compile-ifunc.exp b/gdb/testsuite/gdb.compile/compile-ifunc.exp new file mode 100644 index 0000000..9e83c46 --- /dev/null +++ b/gdb/testsuite/gdb.compile/compile-ifunc.exp @@ -0,0 +1,54 @@ +# Copyright 2015 Free Software Foundation, Inc. + +# 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, see . + +standard_testfile + +if { [prepare_for_testing ${testfile}.exp "$testfile-nodebug" $srcfile {}] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +if {[skip_compile_feature_tests]} { + untested "compile command not supported (could not find libcc1 shared library?)" + return -1 +} + +with_test_prefix "nodebug" { + + gdb_test_no_output "compile code resultvar = gnu_ifunc (10);" + + gdb_test "p resultvar" " = 11" + +} + +if { [prepare_for_testing ${testfile}.exp "$testfile-debug" $srcfile] } { + return -1 +} + +if ![runto_main] { + return -1 +} + +with_test_prefix "debug" { + + # gnu_ifunc (10): error: too many arguments to function 'gnu_ifunc' + gdb_test_no_output "compile code resultvar = gnu_ifunc_alias (10);" + + gdb_test "p resultvar" " = 11" + +}