From patchwork Mon Sep 7 20:47:20 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 8594 Received: (qmail 83464 invoked by alias); 7 Sep 2015 20:47:27 -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 83449 invoked by uid 89); 7 Sep 2015 20:47:27 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL, BAYES_00, KAM_LAZY_DOMAIN_SECURITY, 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; Mon, 07 Sep 2015 20:47:25 +0000 Received: from int-mx13.intmail.prod.int.phx2.redhat.com (int-mx13.intmail.prod.int.phx2.redhat.com [10.5.11.26]) by mx1.redhat.com (Postfix) with ESMTPS id 8E3F2341AF2 for ; Mon, 7 Sep 2015 20:47:24 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-22.ams2.redhat.com [10.36.116.22]) by int-mx13.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t87KlKhp006390 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-GCM-SHA384 bits=256 verify=NO) for ; Mon, 7 Sep 2015 16:47:23 -0400 Date: Mon, 7 Sep 2015 22:47:20 +0200 From: Jan Kratochvil To: gdb-patches@sourceware.org Subject: [ppc64le] Use skip_entrypoint for skip_trampoline_code Message-ID: <20150907204720.GA535@host1.jankratochvil.net> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.23 (2014-03-12) X-IsSubscribed: yes Hi, ppc64le loses control when stepping between two PLT-called functions inside a shared library: 29 shlib_second (); /* first-hit */^M (gdb) PASS: gdb.base/solib-intra-step.exp: first-hit step^M ^M Program received signal SIGABRT, Aborted.^M 0x00003fffb7cbe578 in __GI_raise (sig=) at ../nptl/sysdeps/unix/sysv/linux/raise.c:56^M 56 return INLINE_SYSCALL (tgkill, 3, pid, selftid, sig);^M (gdb) FAIL: gdb.base/solib-intra-step.exp: second-hit -> 29 shlib_second (); /* first-hit */^M (gdb) PASS: gdb.base/solib-intra-step.exp: first-hit step^M shlib_second () at ./gdb.base/solib-intra-step-lib.c:23^M 23 abort (); /* second-hit */^M (gdb) PASS: gdb.base/solib-intra-step.exp: second-hit This is because gdbarch_skip_trampoline_code() will resolve the final function as shlib_second+0 and place there the breakpoint, but ld.so will jump after the breakpoint - at shlib_second+8 - as it is ELFv2 local symbol optimization: Dump of assembler code for function shlib_second: 0x0000000000000804 <+0>: addis r2,r12,2 0x0000000000000808 <+4>: addi r2,r2,30668 0x000000000000080c <+8>: mflr r0 Currently gdbarch_skip_entrypoint() has been called in skip_prologue_sal() and fill_in_stop_func() but that is not enough. I believe gdbarch_skip_entrypoint() should be called after every gdbarch_skip_trampoline_code(), shouldn't it? The attached patch is a bit hack but I am not sure what is a clean solution. Maybe create a gdbarch_skip_trampoline_code() wrapper function calling also gdbarch_skip_entrypoint() and forbid calling gdbarch_skip_trampoline_code() directly? No regressions on ppc64le-rhel7-linux-gnu. Jan gdb/ChangeLog 2015-09-07 Jan Kratochvil * ppc64-tdep.c (ppc64_skip_trampoline_code): Rename to ... (ppc64_skip_trampoline_code_1): ... here. (ppc64_skip_trampoline_code): New wrapper function. gdb/testsuite/ChangeLog 2015-09-07 Jan Kratochvil * gdb.base/solib-intra-step-lib.c: New file. * gdb.base/solib-intra-step-main.c: New file. * gdb.base/solib-intra-step.exp: New file. diff --git a/gdb/ppc64-tdep.c b/gdb/ppc64-tdep.c index bb23b6a..d3c0ece 100644 --- a/gdb/ppc64-tdep.c +++ b/gdb/ppc64-tdep.c @@ -454,8 +454,8 @@ ppc64_standard_linkage4_target (struct frame_info *frame, When the execution direction is EXEC_REVERSE, scan backward to check whether we are in the middle of a PLT stub. */ -CORE_ADDR -ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) +static CORE_ADDR +ppc64_skip_trampoline_code_1 (struct frame_info *frame, CORE_ADDR pc) { #define MAX(a,b) ((a) > (b) ? (a) : (b)) unsigned int insns[MAX (MAX (MAX (ARRAY_SIZE (ppc64_standard_linkage1), @@ -530,6 +530,18 @@ ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) return 0; } +/* Wrapper of ppc64_skip_trampoline_code_1 checking also + ppc_elfv2_skip_entrypoint. */ + +CORE_ADDR +ppc64_skip_trampoline_code (struct frame_info *frame, CORE_ADDR pc) +{ + pc = ppc64_skip_trampoline_code_1 (frame, pc); + if (pc != 0) + pc = gdbarch_skip_entrypoint (get_frame_arch (frame), pc); + return pc; +} + /* Support for convert_from_func_ptr_addr (ARCH, ADDR, TARG) on PPC64 GNU/Linux. diff --git a/gdb/testsuite/gdb.base/solib-intra-step-lib.c b/gdb/testsuite/gdb.base/solib-intra-step-lib.c new file mode 100644 index 0000000..07b72cf --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-intra-step-lib.c @@ -0,0 +1,30 @@ +/* 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 + +void +shlib_second (void) +{ + abort (); /* second-hit */ +} + +void +shlib_first (void) +{ + shlib_second (); /* first-hit */ +} diff --git a/gdb/testsuite/gdb.base/solib-intra-step-main.c b/gdb/testsuite/gdb.base/solib-intra-step-main.c new file mode 100644 index 0000000..186bd5f --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-intra-step-main.c @@ -0,0 +1,25 @@ +/* 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 . */ + +extern void shlib_first (void); + +int +main (void) +{ + shlib_first (); + return 0; +} diff --git a/gdb/testsuite/gdb.base/solib-intra-step.exp b/gdb/testsuite/gdb.base/solib-intra-step.exp new file mode 100644 index 0000000..5666ede --- /dev/null +++ b/gdb/testsuite/gdb.base/solib-intra-step.exp @@ -0,0 +1,52 @@ +# 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 {[skip_shlib_tests]} { + return 0 +} + +# Library file. +set libname "${testfile}-lib" +set srcfile_lib ${srcdir}/${subdir}/${libname}.c +set binfile_lib [standard_output_file ${libname}.so] +set lib_flags [list debug] +# Binary file. +set testfile "${testfile}-main" +set srcfile ${srcdir}/${subdir}/${testfile}.c +set binfile [standard_output_file ${testfile}] +set bin_flags [list debug shlib=${binfile_lib}] + +if [get_compiler_info] { + return -1 +} + +if { [gdb_compile_shlib ${srcfile_lib} ${binfile_lib} $lib_flags] != "" + || [gdb_compile ${srcfile} ${binfile} executable $bin_flags] != "" } { + untested "Could not compile $binfile_lib or $binfile." + return -1 +} + +clean_restart ${binfile} +gdb_load_shlibs $binfile_lib + +if ![runto_main] then { + return 0 +} + +gdb_test "step" " first-hit .*" "first-hit" + +gdb_test "step" " second-hit .*" "second-hit"