From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13684 invoked by alias); 11 Dec 2002 02:43:10 -0000 Mailing-List: contact gdb-patches-help@sources.redhat.com; run by ezmlm Precedence: bulk List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sources.redhat.com Received: (qmail 13672 invoked from network); 11 Dec 2002 02:43:07 -0000 Received: from unknown (HELO localhost.redhat.com) (216.138.202.10) by sources.redhat.com with SMTP; 11 Dec 2002 02:43:07 -0000 Received: from redhat.com (localhost [127.0.0.1]) by localhost.redhat.com (Postfix) with ESMTP id 4EDF83C17 for ; Tue, 10 Dec 2002 21:42:49 -0500 (EST) Message-ID: <3DF6A627.9060700@redhat.com> Date: Tue, 10 Dec 2002 20:27:00 -0000 From: Andrew Cagney User-Agent: Mozilla/5.0 (X11; U; NetBSD macppc; en-US; rv:1.0.0) Gecko/20020824 X-Accept-Language: en-us, en MIME-Version: 1.0 To: gdb-patches@sources.redhat.com Subject: [patch/rfc] Unwind the PC first when creating a frame Content-Type: multipart/mixed; boundary="------------030001040908050201000700" X-SW-Source: 2002-12/txt/msg00353.txt.bz2 This is a multi-part message in MIME format. --------------030001040908050201000700 Content-Type: text/plain; charset=us-ascii; format=flowed Content-Transfer-Encoding: 7bit Content-length: 649 Hello, This patch changes the frame creation code so that it can unwind the PC before doing anything else. By unwinding the PC first, it becomes possible to correctly set the frame from the outset. The old code would set the frame's type last (resulting in architecture code having to back patch it). It also (at least in theory) makes it possible to avoid certain frame unwinds. Since, right now, all architectures currently specify a deprecated init frame pc method, the code isn't used by any architecture. A follow on will be to enable the code on at least one architecture. I'll commit the attached in a few days, enjoy, Andrew --------------030001040908050201000700 Content-Type: text/plain; name="diffs" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="diffs" Content-length: 5285 2002-12-10 Andrew Cagney * frame.c (frame_type_from_pc): New function. (create_new_frame): Use frame_type_from_pc instead of custom code. (get_prev_frame): When neither DEPRECATED_INIT_FRAME_PC_P nor DEPRECATED_INIT_FRAME_PC_FIRST_P use frame_type_from_pc and frame_pc_unwind to set the frame's type at the point of frame creation. Index: frame.c =================================================================== RCS file: /cvs/src/src/gdb/frame.c,v retrieving revision 1.40 diff -u -r1.40 frame.c --- frame.c 11 Dec 2002 02:26:35 -0000 1.40 +++ frame.c 11 Dec 2002 02:33:57 -0000 @@ -767,6 +767,29 @@ } } +/* Determine the frame's type based on its PC. */ + +static enum frame_type +frame_type_from_pc (CORE_ADDR pc) +{ + /* FIXME: cagney/2002-11-24: Can't yet directly call + pc_in_dummy_frame() as some architectures don't set + PC_IN_CALL_DUMMY() to generic_pc_in_call_dummy() (remember the + latter is implemented by simply calling pc_in_dummy_frame). */ + if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + && PC_IN_CALL_DUMMY (pc, 0, 0)) + return DUMMY_FRAME; + else + { + char *name; + find_pc_partial_function (pc, &name, NULL, NULL); + if (PC_IN_SIGTRAMP (pc, name)) + return SIGTRAMP_FRAME; + else + return NORMAL_FRAME; + } +} + /* Create an arbitrary (i.e. address specified by user) or innermost frame. Always returns a non-NULL value. */ @@ -785,30 +808,7 @@ fi->frame = addr; fi->pc = pc; - /* NOTE: cagney/2002-11-18: The code segments, found in - create_new_frame and get_prev_frame(), that initializes the - frames type is subtly different. The latter only updates ->type - when it encounters a SIGTRAMP_FRAME or DUMMY_FRAME. This stops - get_prev_frame() overriding the frame's type when the INIT code - has previously set it. This is really somewhat bogus. The - initialization, as seen in create_new_frame(), should occur - before the INIT function has been called. */ - if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES - && (DEPRECATED_PC_IN_CALL_DUMMY_P () - ? DEPRECATED_PC_IN_CALL_DUMMY (pc, 0, 0) - : pc_in_dummy_frame (pc))) - /* NOTE: cagney/2002-11-11: Does this even occure? */ - type = DUMMY_FRAME; - else - { - char *name; - find_pc_partial_function (pc, &name, NULL, NULL); - if (PC_IN_SIGTRAMP (fi->pc, name)) - type = SIGTRAMP_FRAME; - else - type = NORMAL_FRAME; - } - fi->type = type; + fi->type = frame_type_from_pc (pc); if (INIT_EXTRA_FRAME_INFO_P ()) INIT_EXTRA_FRAME_INFO (0, fi); @@ -867,6 +867,8 @@ CORE_ADDR address = 0; struct frame_info *prev; int fromleaf; + CORE_ADDR pc; + enum frame_type type; /* Return the inner-most frame, when the caller passes in NULL. */ /* NOTE: cagney/2002-11-09: Not sure how this would happen. The @@ -895,6 +897,41 @@ return next_frame->prev; next_frame->prev_p = 1; + /* Try to unwind the PC. If that doesn't work, assume we've reached + the oldest frame and simply return. Is there a better sentinal + value? The unwound PC value is then used to initialize the new + previous frame's type. + + Note that the pc-unwind is intentionally performed before the + frame chain. This is (well should be ok) since, for old targets, + both frame_pc_unwind (nee, FRAME_SAVED_PC) and FRAME_CHAIN()) + assume NEXT_FRAME's data structures have already been initialized + (using INIT_EXTRA_FRAME_INFO) and hence the call order doesn't + matter. + + By unwinding the PC first, it becomes possible to, in the case of + a dummy frame, avoid also unwinding the frame ID. This is + because (well ignoring the PPC) a dummy frame can be located + using NEXT_FRAME's frame ID. + + For the moment this is only done conditionally. Some targets + (e.g., rs6000) appear to break when this change is enabled. */ + if (DEPRECATED_INIT_FRAME_PC_P () + || DEPRECATED_INIT_FRAME_PC_FIRST_P ()) + { + /* Ulgh, old style target that still uses one of the + INIT_FRAME_PC methods. */ + pc = 0; + type = 0; + } + else + { + pc = frame_pc_unwind (next_frame); + if (pc == 0) + return NULL; + type = frame_type_from_pc (pc); + } + /* On some machines it is possible to call a function without setting up a stack frame for it. On these machines, we define this macro to take two args; a frameinfo pointer @@ -1080,12 +1117,15 @@ has previously set it. This is really somewhat bogus. The initialization, as seen in create_new_frame(), should occur before the INIT function has been called. */ - if (DEPRECATED_USE_GENERIC_DUMMY_FRAMES + if ((DEPRECATED_INIT_FRAME_PC_P () + || DEPRECATED_INIT_FRAME_PC_FIRST_P ()) + && DEPRECATED_USE_GENERIC_DUMMY_FRAMES && (DEPRECATED_PC_IN_CALL_DUMMY_P () ? DEPRECATED_PC_IN_CALL_DUMMY (prev->pc, 0, 0) : pc_in_dummy_frame (prev->pc))) prev->type = DUMMY_FRAME; - else + else if (DEPRECATED_INIT_FRAME_PC_P () + || DEPRECATED_INIT_FRAME_PC_FIRST_P ()) { /* FIXME: cagney/2002-11-10: This should be moved to before the INIT code above so that the INIT code knows what the frame's --------------030001040908050201000700--