From patchwork Sun Nov 30 03:40:31 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yao Qi X-Patchwork-Id: 4013 Received: (qmail 19109 invoked by alias); 30 Nov 2014 03:40:38 -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 18969 invoked by uid 89); 30 Nov 2014 03:40:37 -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, RCVD_IN_DNSWL_NONE 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; Sun, 30 Nov 2014 03:40:35 +0000 Received: from svr-orw-fem-03.mgc.mentorg.com ([147.34.97.39]) by relay1.mentorg.com with esmtp id 1XuvN9-0006LP-UA from Yao_Qi@mentor.com for gdb-patches@sourceware.org; Sat, 29 Nov 2014 19:40:31 -0800 Received: from qiyao.dyndns.org.com (147.34.91.1) by svr-orw-fem-03.mgc.mentorg.com (147.34.97.39) with Microsoft SMTP Server id 14.3.181.6; Sat, 29 Nov 2014 19:40:31 -0800 From: Yao Qi To: Subject: [PATCH 2/2] Improve arm_skip_prologue by using arm_analyze_prologue Date: Sun, 30 Nov 2014 11:40:31 +0800 Message-ID: <1417318831-1522-3-git-send-email-yao@codesourcery.com> In-Reply-To: <1417318831-1522-1-git-send-email-yao@codesourcery.com> References: <1417318831-1522-1-git-send-email-yao@codesourcery.com> MIME-Version: 1.0 X-IsSubscribed: yes Hi, I see many fails in dw2-dir-file-name.exp on arm target when test case is compiled with -marm, however, these fails are disappeared when test case is compiled with -mthumb. The difference of pass and fail shown below is that "0x000085d4 in" isn't printed out, but test case expects to see it. -Breakpoint 2, compdir_missing__ldir_missing__file_basename () at tmp-dw2-dir-file-name.c:999^M -(gdb) FAIL: gdb.dwarf2/dw2-dir-file-name.exp: compdir_missing__ldir_missing__file_basename: continue to breakpoint: compdir_missing__ldir_missing__file_basename +Breakpoint 2, 0x000085d4 in compdir_missing__ldir_missing__file_basename () at tmp-dw2-dir-file-name.c:999^M +(gdb) PASS: gdb.dwarf2/dw2-dir-file-name.exp: compdir_missing__ldir_missing__file_basename: continue to breakpoint: compdir_missing__ldir_missing__file_basename This difference is caused by setting breakpoint at the first instruction in the function (actually, the first instruction in prologue, at [1]), so that frame_show_address returns false, and print_frame doesn't print the address. 0x00008620 <+0>: push {r11} ; (str r11, [sp, #-4]!) <--[1] 0x00008624 <+4>: add r11, sp, #0 0x00008628 <+8>: ldr r3, [pc, #24] ; 0x8648 0x0000862c <+12>: ldr r3, [r3] 0x00008630 <+16>: add r3, r3, #1 0x00008634 <+20>: ldr r2, [pc, #12] ; 0x8648 Then, it must be the arm_skip_prologue's fault that unable to skip instructions in prologue. At the end of arm_skip_prologue, it matches several instructions, such as "str r(0123),[r11,#-nn]" and "str r(0123),[sp,#nn]", but "push {r11}" isn't handled. These instruction matching code in arm_skip_prologue, which can be regarded as leftover of development for many years, should be merged to arm_analyze_prologue and use arm_analyze_prologue in arm_skip_prologue. Here is the something like the history of arm_{skip,scan,analyze}_prologue. Around 2002, there are arm_skip_prologue and arm_scan_prologue, but code are duplicated to some extent. When match an instruction, both functions should be modified, for example in Michael Snyder's patch https://sourceware.org/ml/gdb-patches/2002-05/msg00205.html and Michael expressed the willingness to merge both into one. Daniel added code call thumb_analyze_prologue in arm_skip_prologue in 2006, but didn't handle its counterpart arm_analyze_prologue, which is added in 2010 however, the instructions matching at the bottom of arm_skip_prologue wasn't cleaned up. This patch is to merge them into arm_analyze_prologue. Note 1: I recall some one opened a PR for these fails, but I can't find it in bugzilla. Note 2: This patch should also fix PR 14261, but I don't have a CLANG to test it. gdb: 2014-11-30 Yao Qi * arm-tdep.c (arm_skip_prologue): Remove unused local variable 'skip_pc'. Remove code skipping prologue instructions, use arm_analyze_prologue instead. (arm_analyze_prologue): Stop the scanning for unrecognized instruction when skipping prologue. --- gdb/arm-tdep.c | 75 ++++++++++------------------------------------------------ 1 file changed, 12 insertions(+), 63 deletions(-) diff --git a/gdb/arm-tdep.c b/gdb/arm-tdep.c index 3407045..a4f99c5 100644 --- a/gdb/arm-tdep.c +++ b/gdb/arm-tdep.c @@ -1388,7 +1388,6 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) { enum bfd_endian byte_order_for_code = gdbarch_byte_order_for_code (gdbarch); unsigned long inst; - CORE_ADDR skip_pc; CORE_ADDR func_addr, limit_pc; /* See if we can determine the end of the prologue via the symbol table. @@ -1462,65 +1461,8 @@ arm_skip_prologue (struct gdbarch *gdbarch, CORE_ADDR pc) /* Check if this is Thumb code. */ if (arm_pc_is_thumb (gdbarch, pc)) return thumb_analyze_prologue (gdbarch, pc, limit_pc, NULL); - - for (skip_pc = pc; skip_pc < limit_pc; skip_pc += 4) - { - inst = read_memory_unsigned_integer (skip_pc, 4, byte_order_for_code); - - /* "mov ip, sp" is no longer a required part of the prologue. */ - if (inst == 0xe1a0c00d) /* mov ip, sp */ - continue; - - if ((inst & 0xfffff000) == 0xe28dc000) /* add ip, sp #n */ - continue; - - if ((inst & 0xfffff000) == 0xe24dc000) /* sub ip, sp #n */ - continue; - - /* Some prologues begin with "str lr, [sp, #-4]!". */ - if (inst == 0xe52de004) /* str lr, [sp, #-4]! */ - continue; - - if ((inst & 0xfffffff0) == 0xe92d0000) /* stmfd sp!,{a1,a2,a3,a4} */ - continue; - - if ((inst & 0xfffff800) == 0xe92dd800) /* stmfd sp!,{fp,ip,lr,pc} */ - continue; - - /* Any insns after this point may float into the code, if it makes - for better instruction scheduling, so we skip them only if we - find them, but still consider the function to be frame-ful. */ - - /* We may have either one sfmfd instruction here, or several stfe - insns, depending on the version of floating point code we - support. */ - if ((inst & 0xffbf0fff) == 0xec2d0200) /* sfmfd fn, , [sp]! */ - continue; - - if ((inst & 0xffff8fff) == 0xed6d0103) /* stfe fn, [sp, #-12]! */ - continue; - - if ((inst & 0xfffff000) == 0xe24cb000) /* sub fp, ip, #nn */ - continue; - - if ((inst & 0xfffff000) == 0xe24dd000) /* sub sp, sp, #nn */ - continue; - - if ((inst & 0xffffc000) == 0xe54b0000 /* strb r(0123),[r11,#-nn] */ - || (inst & 0xffffc0f0) == 0xe14b00b0 /* strh r(0123),[r11,#-nn] */ - || (inst & 0xffffc000) == 0xe50b0000) /* str r(0123),[r11,#-nn] */ - continue; - - if ((inst & 0xffffc000) == 0xe5cd0000 /* strb r(0123),[sp,#nn] */ - || (inst & 0xffffc0f0) == 0xe1cd00b0 /* strh r(0123),[sp,#nn] */ - || (inst & 0xffffc000) == 0xe58d0000) /* str r(0123),[sp,#nn] */ - continue; - - /* Un-recognized instruction; stop scanning. */ - break; - } - - return skip_pc; /* End of prologue. */ + else + return arm_analyze_prologue (gdbarch, pc, limit_pc, NULL); } /* *INDENT-OFF* */ @@ -1905,10 +1847,17 @@ arm_analyze_prologue (struct gdbarch *gdbarch, continue; else { - /* The optimizer might shove anything into the prologue, - so we just skip what we don't recognize. */ + /* The optimizer might shove anything into the prologue, if + we build up cache (cache != NULL) from scanning prologue, + we just skip what we don't recognize and scan further to + make cache as complete as possible. However, if we skip + prologue, we'll stop immediately on unrecognized + instruction. */ unrecognized_pc = current_pc; - continue; + if (cache != NULL) + continue; + else + break; } }