From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 7778 invoked by alias); 12 Jan 2006 23:53:36 -0000 Received: (qmail 7766 invoked by uid 22791); 12 Jan 2006 23:53:35 -0000 X-Spam-Check-By: sourceware.org Received: from e35.co.us.ibm.com (HELO e35.co.us.ibm.com) (32.97.110.153) by sourceware.org (qpsmtpd/0.31) with ESMTP; Thu, 12 Jan 2006 23:53:34 +0000 Received: from westrelay02.boulder.ibm.com (westrelay02.boulder.ibm.com [9.17.195.11]) by e35.co.us.ibm.com (8.12.11/8.12.11) with ESMTP id k0CNrWbT009706 for ; Thu, 12 Jan 2006 18:53:32 -0500 Received: from d03av02.boulder.ibm.com (d03av02.boulder.ibm.com [9.17.195.168]) by westrelay02.boulder.ibm.com (8.12.10/NCO/VERS6.8) with ESMTP id k0CNq3pC262766 for ; Thu, 12 Jan 2006 16:52:03 -0700 Received: from d03av02.boulder.ibm.com (loopback [127.0.0.1]) by d03av02.boulder.ibm.com (8.12.11/8.13.3) with ESMTP id k0CNrWXn022528 for ; Thu, 12 Jan 2006 16:53:32 -0700 Received: from dyn9047022123-009047022095.beaverton.ibm.com (dyn9047022123-009047022095.beaverton.ibm.com [9.47.22.95]) by d03av02.boulder.ibm.com (8.12.11/8.12.11) with ESMTP id k0CNrWkL022488; Thu, 12 Jan 2006 16:53:32 -0700 From: Paul Gilliam Reply-To: pgilliam@us.ibm.com To: gdb-patches@sourceware.org Subject: Re: [PATCH] add 'rs6000_in_function_epilogue_p()' (Revised) Date: Thu, 12 Jan 2006 23:53:00 -0000 User-Agent: KMail/1.6.2 Cc: Kevin Buettner , Mark Kettenis References: <200511301225.56802.pgilliam@us.ibm.com> <200601111013.24433.pgilliam@us.ibm.com> <200601111511.27699.pgilliam@us.ibm.com> In-Reply-To: <200601111511.27699.pgilliam@us.ibm.com> MIME-Version: 1.0 Content-Disposition: inline Content-Type: Multipart/Mixed; boundary="Boundary-00=_zLvxD7KcZHVKBT6" Message-Id: <200601121623.15363.pgilliam@us.ibm.com> X-IsSubscribed: yes Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org X-SW-Source: 2006-01/txt/msg00133.txt.bz2 --Boundary-00=_zLvxD7KcZHVKBT6 Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable Content-Disposition: inline Content-length: 1007 [I am reposting this because it did not show up in the mail-list archive] On Wednesday 11 January 2006 10:13, Paul Gilliam wrote: > Kevin and Mark, >=20 > I kind of lost track of this. =A0Here is a link to the revised patch. =A0= It should address Mark's concerns, > but I thought, sense it's been a while, I should run it by you again. >=20 > http://sourceware.org/ml/gdb-patches/2005-12/msg00072.html >=20 > OK to commit? >=20 > -=3D# Paul #=3D- >=20 > On Friday 02 December 2005 12:32, Kevin Buettner wrote: > > On Fri, 2 Dec 2005 11:20:22 -0800 > > Paul Gilliam wrote: > >=20 > > > =A0 =A0 =A0 =A0 * rs6000-tdep.c: Add new subroutine, 'rs6000_in_funct= ion_epilogue_p()' > > > =A0 =A0 =A0 =A0 and put it into the architecture vector. > >=20 > > Your patch is okay to commit after you address Mark's concerns. > >=20 > > Kevin > >=20 > >=20 >=20 >=20 >=20 I found I had a more up-to-date version of the patch that should address bo= th Mark's concerns and Kevin's OK to commit? --Boundary-00=_zLvxD7KcZHVKBT6 Content-Type: text/x-diff; charset="iso-8859-1"; name="watch-locals.patch" Content-Transfer-Encoding: 7bit Content-Disposition: attachment; filename="watch-locals.patch" Content-length: 5107 2006-01-11 Paul Gilliam * ppc-tdep.h: Add a define for the hard limit used when scanning an epilogue. * rs6000-tdep.c: Add new subroutine, 'rs6000_in_function_epilogue_p()' and put it into the architecture vector. Index: ppc-tdep.h =================================================================== RCS file: /cvs/src/src/gdb/ppc-tdep.h,v retrieving revision 1.48 diff -a -u -r1.48 ppc-tdep.h --- ppc-tdep.h 28 Oct 2005 18:23:32 -0000 1.48 +++ ppc-tdep.h 11 Jan 2006 23:03:43 -0000 @@ -384,4 +384,7 @@ /* Instruction size. */ #define PPC_INSN_SIZE 4 +/* Estimate for the maximum number of instrctions in a function epilogue. */ +#define PPC_MAX_EPILOGUE_INSTRUCTIONS 52 + #endif /* ppc-tdep.h */ Index: rs6000-tdep.c =================================================================== RCS file: /cvs/src/src/gdb/rs6000-tdep.c,v retrieving revision 1.248 diff -a -u -r1.248 rs6000-tdep.c --- rs6000-tdep.c 1 Nov 2005 19:32:36 -0000 1.248 +++ rs6000-tdep.c 11 Jan 2006 23:03:43 -0000 @@ -502,6 +502,114 @@ return pc; } +static int +insn_changes_sp_or_jumps (unsigned long insn) +{ + int opcode = (insn >> 26) & 0x03f; + int sd = (insn >> 21) & 0x01f; + int a = (insn >> 16) & 0x01f; + /* b = (insn >> 11) & 0x01f */ + int subcode = (insn >> 1) & 0x3ff; + /* rc = insn & 0x001 */ + + /* Changes the stack pointer. */ + + /* NOTE: There are many ways to change the value of a given register. + The ways below are those used when the register is R1, the SP, + in a funtion's epilogue. */ + + if (opcode == 31 && subcode == 444 && a == 1) + return 1; /* mr R1,Rn */ + if (opcode == 14 && sd == 1) + return 1; /* addi R1,Rn,simm */ + if (opcode == 58 && sd == 1) + return 1; /* ld R1,ds(Rn) */ + + /* Transfers control. */ + + if (opcode == 18) + return 1; /* b */ + if (opcode == 16) + return 1; /* bc */ + if (opcode == 19 && subcode == 16) + return 1; /* bclr */ + if (opcode == 19 && subcode == 528) + return 1; /* bcctr */ + + return 0; +} + +/* Return true if we are in the function's epilogue, i.e. after the + instruction that destroyed the function's stack frame. + + 1) scan forward from the point of execution: + a) If you find an instruction that modifies the stack pointer + or transfers control (except a return), execution is not in + an epilogue, return. + b) Stop scanning if you find a return instruction or reach the + end of the function or reach the hard limit for the size of + an epilogue. + 2) scan backward from the point of execution: + a) If you find an instruction that modifies the stack pointer, + execution *is* in an epilogue, return. + b) Stop scanning if you reach an instruction that transfers + control or the beginning of the function or reach the hard + limit for the size of an epilogue. */ + +static int +rs6000_in_function_epilogue_p (struct gdbarch *gdbarch, CORE_ADDR pc) +{ + bfd_byte insn_buf[PPC_INSN_SIZE]; + CORE_ADDR scan_pc, func_start, func_end, epilogue_start, epilogue_end; + unsigned long insn; + struct frame_info *fr; + + /* Find the search limits based on function boundaries and hard limit. */ + + if (!find_pc_partial_function (pc, NULL, &func_start, &func_end)) + return 0; + + epilogue_start = pc - PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE; + if (epilogue_start < func_start) epilogue_start = func_start; + + epilogue_end = pc + PPC_MAX_EPILOGUE_INSTRUCTIONS * PPC_INSN_SIZE; + if (epilogue_end > func_end) epilogue_end = func_end; + + /* Get the current frame. This may be cheap, since we might have + just called it in watchpoint_check, before calling + gdbarch_in_function_epilogue_p. */ + + fr = get_current_frame (); + + /* Scan forward until next 'blr'. */ + + for (scan_pc = pc; scan_pc < epilogue_end; scan_pc += PPC_INSN_SIZE) + { + if (!safe_frame_unwind_memory (fr, scan_pc, insn_buf, PPC_INSN_SIZE)) + return 0; + insn = extract_signed_integer (insn_buf, PPC_INSN_SIZE); + if (insn == 0x4e800020) + break; + if (insn_changes_sp_or_jumps (insn)) + return 0; + } + + /* Scan backward until adjustment to stack pointer (R1). */ + + for (scan_pc = pc - PPC_INSN_SIZE; + scan_pc >= epilogue_start; + scan_pc -= PPC_INSN_SIZE) + { + if (!safe_frame_unwind_memory (fr, scan_pc, insn_buf, PPC_INSN_SIZE)) + return 0; + insn = extract_signed_integer (insn_buf, PPC_INSN_SIZE); + if (insn_changes_sp_or_jumps (insn)) + return 1; + } + + return 0; +} + /* Fill in fi->saved_regs */ @@ -3342,6 +3450,8 @@ set_gdbarch_deprecated_extract_struct_value_address (gdbarch, rs6000_extract_struct_value_address); set_gdbarch_skip_prologue (gdbarch, rs6000_skip_prologue); + set_gdbarch_in_function_epilogue_p (gdbarch, rs6000_in_function_epilogue_p); + set_gdbarch_inner_than (gdbarch, core_addr_lessthan); set_gdbarch_breakpoint_from_pc (gdbarch, rs6000_breakpoint_from_pc); --Boundary-00=_zLvxD7KcZHVKBT6--