From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 10195 invoked by alias); 25 Nov 2014 00:03:16 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 10185 invoked by uid 89); 25 Nov 2014 00:03:16 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 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; Tue, 25 Nov 2014 00:03:13 +0000 Received: from svr-orw-fem-05.mgc.mentorg.com ([147.34.97.43]) by relay1.mentorg.com with esmtp id 1Xt3b4-0000lU-1q from Sandra_Loosemore@mentor.com for gdb-patches@sourceware.org; Mon, 24 Nov 2014 16:03:10 -0800 Received: from [IPv6:::1] (147.34.91.1) by svr-orw-fem-05.mgc.mentorg.com (147.34.97.43) with Microsoft SMTP Server id 14.3.181.6; Mon, 24 Nov 2014 16:03:09 -0800 Message-ID: <5473C736.6050501@codesourcery.com> Date: Tue, 25 Nov 2014 00:03:00 -0000 From: Sandra Loosemore User-Agent: Mozilla/5.0 (X11; Linux i686; rv:17.0) Gecko/20130329 Thunderbird/17.0.5 MIME-Version: 1.0 To: Yao Qi , Subject: [2/3 patch, nios2] clean up prologue/epilogue detection code, v2 References: <545EA0C1.6050104@codesourcery.com> <87bnoeif74.fsf@codesourcery.com> <5473C4BA.2050903@codesourcery.com> In-Reply-To: <5473C4BA.2050903@codesourcery.com> Content-Type: multipart/mixed; boundary="------------080209060403020907000608" X-SW-Source: 2014-11/txt/msg00617.txt.bz2 --------------080209060403020907000608 Content-Type: text/plain; charset="UTF-8"; format=flowed Content-Transfer-Encoding: 7bit Content-length: 233 This part of the revised Nios II prologue/epilogue refactoring patch set fixes the epilogue detection code to deal with the multiple stack adjustments that GCC may now emit in some cases. OK to commit on top of part 1? -Sandra --------------080209060403020907000608 Content-Type: text/x-log; name="gdb-nios2-epilogue-2.log" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gdb-nios2-epilogue-2.log" Content-length: 138 2014-11-24 Sandra Loosemore gdb/ * nios2-tdep.c (nios2_in_epilogue_p): Handle multiple stack adjustments. --------------080209060403020907000608 Content-Type: text/x-patch; name="gdb-nios2-epilogue-2.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="gdb-nios2-epilogue-2.patch" Content-length: 2943 diff -u b/gdb/nios2-tdep.c b/gdb/nios2-tdep.c --- b/gdb/nios2-tdep.c +++ b/gdb/nios2-tdep.c @@ -589,26 +589,42 @@ CORE_ADDR start_pc) { unsigned long mach = gdbarch_bfd_arch_info (gdbarch)->mach; + /* Maximum number of possibly-epilogue instructions to check. + Note that this number should not be too large, else we can + potentially end up iterating through unmapped memory. */ + int ninsns, max_insns = 5; unsigned int insn; const struct nios2_opcode *op = NULL; unsigned int uimm; int imm; int ra, rb, rc; enum branch_condition cond; + CORE_ADDR pc; /* There has to be a previous instruction in the function. */ - if (current_pc > start_pc) - { - int ok = 0; + if (current_pc <= start_pc) + return 0; - /* Check whether the previous instruction was a stack adjustment. - Possible instructions here include: + /* Find the previous instruction before current_pc. + For the moment we will assume that all instructions are the + same size here. */ + pc = current_pc - NIOS2_OPCODE_SIZE; + + /* Beginning with the previous instruction we just located, check whether + we are in a sequence of at least one stack adjustment instruction. + Possible instructions here include: ADDI sp, sp, n ADD sp, sp, rn LDW sp, n(sp) */ - op = nios2_fetch_insn (gdbarch, current_pc - NIOS2_OPCODE_SIZE, &insn); + for (ninsns = 0; ninsns < max_insns; ninsns++) + { + int ok = 0; + + /* Fetch the insn at pc. */ + op = nios2_fetch_insn (gdbarch, pc, &insn); if (op == NULL) return 0; + pc += op->size; /* Was it a stack adjustment? */ if (nios2_match_addi (insn, op, mach, &ra, &rb, &imm)) @@ -618,18 +634,27 @@ else if (nios2_match_ldw (insn, op, mach, &ra, &rb, &imm)) ok = (rb == NIOS2_SP_REGNUM); if (!ok) - return 0; - - /* Then check if it's followed by a return or a tail call. */ - op = nios2_fetch_insn (gdbarch, current_pc, &insn); - if (op == NULL) - return 0; - if (nios2_match_jmpr (insn, op, mach, &ra) - || nios2_match_jmpi (insn, op, mach, &uimm) - || (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond) - && cond == branch_none)) - return 1; + break; } + + /* No stack adjustments found. */ + if (ninsns == 0) + return 0; + + /* We found more stack adjustments than we expect GCC to be generating. + Since it looks like a stack unwind might be in progress tell GDB to + treat it as such. */ + if (ninsns == max_insns) + return 1; + + /* The next instruction following the stack adjustments must be a + return, jump, or unconditional branch. */ + if (nios2_match_jmpr (insn, op, mach, &ra) + || nios2_match_jmpi (insn, op, mach, &uimm) + || (nios2_match_branch (insn, op, mach, &ra, &rb, &imm, &cond) + && cond == branch_none)) + return 1; + return 0; } --------------080209060403020907000608--