From patchwork Mon Jun 9 02:13:02 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 1367 Received: (qmail 32376 invoked by alias); 9 Jun 2014 02:15:23 -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 32350 invoked by uid 89); 9 Jun 2014 02:15:21 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.7 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: relay1.mentorg.com Received: from relay1.mentorg.com (HELO relay1.mentorg.com) (192.94.38.131) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 09 Jun 2014 02:15:19 +0000 Received: from svr-orw-exc-10.mgc.mentorg.com ([147.34.98.58]) by relay1.mentorg.com with esmtp id 1Wtp7E-0005OA-If from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Sun, 08 Jun 2014 19:15:16 -0700 Received: from SVR-ORW-FEM-06.mgc.mentorg.com ([147.34.97.120]) by SVR-ORW-EXC-10.mgc.mentorg.com with Microsoft SMTPSVC(6.0.3790.4675); Sun, 8 Jun 2014 19:15:16 -0700 Received: from qiyao.dyndns.org.com (147.34.91.1) by SVR-ORW-FEM-06.mgc.mentorg.com (147.34.97.120) with Microsoft SMTP Server id 14.2.247.3; Sun, 8 Jun 2014 19:15:15 -0700 From: Yao Qi To: Subject: [PATCH 2/3] Apply stub unwinder to 'bx reg' trampoline Date: Mon, 9 Jun 2014 10:13:02 +0800 Message-ID: <1402279983-1907-3-git-send-email-yao@codesourcery.com> In-Reply-To: <1402279983-1907-1-git-send-email-yao@codesourcery.com> References: <1402279983-1907-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 X-IsSubscribed: yes In target arm-none-eabi, prologue unwinder is used for trampoline 'bx reg'. However, in target arm-linux, exidx unwinder is selected for trampoline at first, which is not expected. The main function and the trampoline is, 0x00009dfc : push {r4, r5, r6, r7, lr} ...... 0x0000ac30 : ldrdeq r3, [r1], -r8 0x0000ac34: bx r2 0x0000ac36: bx r4 and .ARM.exidx is: 0x9dfc
: @0xb404 Compact model index: 1 0x97 vsp = r7 0x20 vsp = vsp + 132 0x3f vsp = vsp + 256 0x80 0xf0 pop {r8, r9, r10, r11} 0xab pop {r4, r5, r6, r7, r14} 0xac38 <__aeabi_drsub>: 0x1 [cantunwind] Trampolines 'bx r2' and 'bx r4' doesn't belong to main, but the exidx for main is still selected form them because there is no end address of each exidx entry. Instead of teaching exidx unwinder ignore this trampoline (which looks complicated and error prone), I decide to let stub unwinder to handle trampoline, because stub undwinder is installed before exidx unwinder, and this trampoline can be regarded as a stub too. This patch is to add the code to match 'bx reg' trampoline in the sniffer of stub unwinder. gdb: 2014-06-09 Yao Qi * arm-tdep.c (arm_skip_bx_reg): Declare. (arm_stub_unwind_sniffer): Return 1 if arm_skip_bx_reg returns non-zero. --- gdb/arm-tdep.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 2430a86..e3f7f0c 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -2899,6 +2899,8 @@ arm_stub_this_id (struct frame_info *this_frame, *this_id = frame_id_build (cache->prev_sp, get_frame_pc (this_frame)); } +static CORE_ADDR arm_skip_bx_reg (struct frame_info *frame, CORE_ADDR pc); + static int arm_stub_unwind_sniffer (const struct frame_unwind *self, struct frame_info *this_frame, @@ -2906,12 +2908,19 @@ arm_stub_unwind_sniffer (const struct frame_unwind *self, { CORE_ADDR addr_in_block; gdb_byte dummy[4]; + CORE_ADDR pc, start_addr; + const char *name; addr_in_block = get_frame_address_in_block (this_frame); + pc = get_frame_pc (this_frame); if (in_plt_section (addr_in_block) /* We also use the stub winder if the target memory is unreadable to avoid having the prologue unwinder trying to read it. */ - || target_read_memory (get_frame_pc (this_frame), dummy, 4) != 0) + || target_read_memory (pc, dummy, 4) != 0) + return 1; + + if (find_pc_partial_function (pc, &name, &start_addr, NULL) == 0 + && arm_skip_bx_reg (this_frame, pc) != 0) return 1; return 0;