From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 64141 invoked by alias); 12 Dec 2018 14:28:57 -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 63637 invoked by uid 89); 12 Dec 2018 14:28:56 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy=Supply, pays, 201809, pc X-HELO: mail-wm1-f65.google.com Received: from mail-wm1-f65.google.com (HELO mail-wm1-f65.google.com) (209.85.128.65) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Wed, 12 Dec 2018 14:28:47 +0000 Received: by mail-wm1-f65.google.com with SMTP id s14so6013598wmh.1 for ; Wed, 12 Dec 2018 06:28:46 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=embecosm.com; s=google; h=date:from:to:subject:message-id:references:mime-version :content-disposition:in-reply-to:user-agent; bh=Mmbr8YfzRAVqf1TXAHHmgL1PZ0YwwrJQn68HfSQ7rwI=; b=U7S45LXE7lWsH2bTp1omylwok1qC2r4tzpF8XLGRD4zGNKQfQeDDLBKYy1xHviO6Lj RHvM+i40TGtVJmSC7CD+mp/yX4nB2w3Or6nCSTG2WKLuUc40zKXaoJpdM7KGToIfHGxS xibZuew42aCEvgAG7x96La+q9q56prT7yeHYOTRfdQlo2RGGbi7R4XbFT+8zoBuo4BrA l+oTl5t4vSYvru9LuBPd1wsr8hY1iK04sYg5KZfb8gN1ZFbmFPpTpkvCIoNdvzBf/JyD kb/2MV6LcNAzh2NKEq3ne/FCksdjQEOpp/fE/fd81TWaXnvyhicz6ipcRpV0Avb1H48o iLyg== Return-Path: Received: from localhost ([2a02:390:741d:1:3665:d267:b319:d766]) by smtp.gmail.com with ESMTPSA id b18sm19538858wrr.43.2018.12.12.06.28.43 for (version=TLS1_2 cipher=ECDHE-RSA-CHACHA20-POLY1305 bits=256/256); Wed, 12 Dec 2018 06:28:43 -0800 (PST) Date: Wed, 12 Dec 2018 14:28:00 -0000 From: Andrew Burgess To: gdb-patches@sourceware.org Subject: PING: Re: [PATCHv5] gdb: Add default frame methods to gdbarch Message-ID: <20181212142842.GH18841@embecosm.com> References: <20181108214357.5364-1-andrew.burgess@embecosm.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20181108214357.5364-1-andrew.burgess@embecosm.com> X-Fortune: Stop searching forever. Happiness is just next to you. X-Editor: GNU Emacs [ http://www.gnu.org/software/emacs ] User-Agent: Mutt/1.9.2 (2017-12-15) X-IsSubscribed: yes X-SW-Source: 2018-12/txt/msg00131.txt.bz2 Ping! Thanks, Andrew * Andrew Burgess [2018-11-08 21:43:57 +0000]: > This is another iteration of a patch that I last posted here: > > https://sourceware.org/ml/gdb-patches/2018-09/msg00127.html > > previous versions can be found here: > > https://sourceware.org/ml/gdb-patches/2018-06/msg00090.html > https://sourceware.org/ml/gdb-patches/2018-03/msg00306.html > https://sourceware.org/ml/gdb-patches/2018-03/msg00165.html > > I believe v4 actually got approved, but, when I went to merge it I > realised I'd made a mistake! > > This new version is mostly the same as v4, but the default_unwind_pc > method is simpler, but will, I think, still cover almost all targets. > > As far as testing, I don't believe that any target will be using these > default methods after this initial commit, however, I did a build with > all targets enabled, and it built fine. > > Out of tree I've tested this on the RISC-V target, with no regressions. > > Is this OK to apply? > > Thanks, > Andrew > > > --- > > Supply default gdbarch methods for gdbarch_dummy_id, > gdbarch_unwind_pc, and gdbarch_unwind_sp. This patch doesn't actually > convert any targets to use these methods, and so, there will be no > user visible changes after this commit. > > The implementations for default_dummy_id and default_unwind_sp are > fairly straight forward, these just take on the pattern used by most > targets. Once these default methods are in place then most targets > will be able to switch over. > > The implementation for default_unwind_pc is also fairly straight > forward, but maybe needs some explanation. > > This patch has gone through a number of iterations: > > https://sourceware.org/ml/gdb-patches/2018-03/msg00165.html > https://sourceware.org/ml/gdb-patches/2018-03/msg00306.html > https://sourceware.org/ml/gdb-patches/2018-06/msg00090.html > https://sourceware.org/ml/gdb-patches/2018-09/msg00127.html > > and the implementation of default_unwind_pc has changed over this > time. Originally, I took an implementation like this: > > CORE_ADDR > default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > { > int pc_regnum = gdbarch_pc_regnum (gdbarch); > return frame_unwind_register_unsigned (next_frame, pc_regnum); > } > > This is basically a clone of default_unwind_sp, but using $pc. It was > pointed out that we could potentially do better, and in version 2 the > implementation became: > > CORE_ADDR > default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > { > struct type *type; > int pc_regnum; > CORE_ADDR addr; > struct value *value; > > pc_regnum = gdbarch_pc_regnum (gdbarch); > value = frame_unwind_register_value (next_frame, pc_regnum); > type = builtin_type (gdbarch)->builtin_func_ptr; > addr = extract_typed_address (value_contents_all (value), type); > addr = gdbarch_addr_bits_remove (gdbarch, addr); > release_value (value); > value_free (value); > return addr; > } > > The idea was to try split out some of the steps of unwinding the $pc, > steps that are on some (or many) targets no-ops, and so allow targets > that do override these methods, to make use of default_unwind_pc. > > This implementation remained in place for version 2, 3, and 4. > > However, I realised that I'd made a mistake, most targets simply use > frame_unwind_register_unsigned to unwind the $pc, and this throws an > error if the register value is optimized out or unavailable. My new > proposed implementation doesn't do this, I was going to end up > breaking many targets. > > I considered duplicating the code from frame_unwind_register_unsigned > that throws the errors into my new default_unwind_pc, however, this > felt really overly complex. So, what I instead went with was to > simply revert back to using frame_unwind_register_unsigned. Almost > all existing targets already use this. Some of the ones that don't can > be converted to, which means almost all targets could end up using the > default. > > One addition I have made over the version 1 implementation is to add a > call to gdbarch_addr_bits_remove. For most targets this is a no-op, > but for a handful, having this call in place will mean that they can > use the default method. After all this, the new default_unwind_pc now > looks like this: > > CORE_ADDR > default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > { > int pc_regnum = gdbarch_pc_regnum (gdbarch); > CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum); > pc = gdbarch_addr_bits_remove (gdbarch, pc); > return pc; > } > > gdb/ChangeLog: > > * gdb/dummy-frame.c (default_dummy_id): Defined new function. > * gdb/dummy-frame.h (default_dummy_id): Declare new function. > * gdb/frame-unwind.c (default_unwind_pc): Define new function. > (default_unwind_sp): Define new function. > * gdb/frame-unwind.h (default_unwind_pc): Declare new function. > (default_unwind_sp): Declare new function. > * gdb/frame.c (frame_unwind_pc): Assume gdbarch_unwind_pc is > available. > (get_frame_sp): Assume that gdbarch_unwind_sp is available. > * gdb/gdbarch.c: Regenerate. > * gdb/gdbarch.h: Regenerate. > * gdb/gdbarch.sh: Update definition of dummy_id, unwind_pc, and > unwind_sp. Add additional header files to be included in > generated file. > --- > gdb/ChangeLog | 17 +++++++ > gdb/dummy-frame.c | 12 +++++ > gdb/dummy-frame.h | 6 +++ > gdb/frame-unwind.c | 20 ++++++++ > gdb/frame-unwind.h | 12 +++++ > gdb/frame.c | 132 ++++++++++++++++++++++++----------------------------- > gdb/gdbarch.c | 41 ++++------------- > gdb/gdbarch.h | 6 --- > gdb/gdbarch.sh | 13 ++++-- > 9 files changed, 144 insertions(+), 115 deletions(-) > > diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c > index c6f874a3b19..8e380ae1c87 100644 > --- a/gdb/dummy-frame.c > +++ b/gdb/dummy-frame.c > @@ -385,6 +385,18 @@ const struct frame_unwind dummy_frame_unwind = > dummy_frame_sniffer, > }; > > +/* See dummy-frame.h. */ > + > +struct frame_id > +default_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) > +{ > + CORE_ADDR sp, pc; > + > + sp = get_frame_sp (this_frame); > + pc = get_frame_pc (this_frame); > + return frame_id_build (sp, pc); > +} > + > static void > fprint_dummy_frames (struct ui_file *file) > { > diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h > index 407f398404e..9eaec3492bf 100644 > --- a/gdb/dummy-frame.h > +++ b/gdb/dummy-frame.h > @@ -73,4 +73,10 @@ extern void register_dummy_frame_dtor (frame_id dummy_id, > extern int find_dummy_frame_dtor (dummy_frame_dtor_ftype *dtor, > void *dtor_data); > > +/* Default implementation of gdbarch_dummy_id. Generate a dummy frame_id > + for THIS_FRAME assuming that the frame is a dummy frame. */ > + > +extern struct frame_id default_dummy_id (struct gdbarch *gdbarch, > + struct frame_info *this_frame); > + > #endif /* !defined (DUMMY_FRAME_H) */ > diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c > index e6e63539ad7..fb0e5e83213 100644 > --- a/gdb/frame-unwind.c > +++ b/gdb/frame-unwind.c > @@ -193,6 +193,26 @@ default_frame_unwind_stop_reason (struct frame_info *this_frame, > return UNWIND_NO_REASON; > } > > +/* See frame-unwind.h. */ > + > +CORE_ADDR > +default_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > +{ > + int pc_regnum = gdbarch_pc_regnum (gdbarch); > + CORE_ADDR pc = frame_unwind_register_unsigned (next_frame, pc_regnum); > + pc = gdbarch_addr_bits_remove (gdbarch, pc); > + return pc; > +} > + > +/* See frame-unwind.h. */ > + > +CORE_ADDR > +default_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) > +{ > + int sp_regnum = gdbarch_sp_regnum (gdbarch); > + return frame_unwind_register_unsigned (next_frame, sp_regnum); > +} > + > /* Helper functions for value-based register unwinding. These return > a (possibly lazy) value of the appropriate type. */ > > diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h > index af220f72a01..3ca3fdfe727 100644 > --- a/gdb/frame-unwind.h > +++ b/gdb/frame-unwind.h > @@ -70,6 +70,18 @@ enum unwind_stop_reason > default_frame_unwind_stop_reason (struct frame_info *this_frame, > void **this_cache); > > +/* A default unwind_pc callback that simply unwinds the register identified > + by GDBARCH_PC_REGNUM. */ > + > +extern CORE_ADDR default_unwind_pc (struct gdbarch *gdbarch, > + struct frame_info *next_frame); > + > +/* A default unwind_sp callback that simply unwinds the register identified > + by GDBARCH_SP_REGNUM. */ > + > +extern CORE_ADDR default_unwind_sp (struct gdbarch *gdbarch, > + struct frame_info *next_frame); > + > /* Assuming the frame chain: (outer) prev <-> this <-> next (inner); > use THIS frame, and through it the NEXT frame's register unwind > method, to determine the frame ID of THIS frame. > diff --git a/gdb/frame.c b/gdb/frame.c > index 4624eada87b..f98a54a9e0f 100644 > --- a/gdb/frame.c > +++ b/gdb/frame.c > @@ -872,76 +872,71 @@ frame_unwind_pc (struct frame_info *this_frame) > { > if (this_frame->prev_pc.status == CC_UNKNOWN) > { > - if (gdbarch_unwind_pc_p (frame_unwind_arch (this_frame))) > + struct gdbarch *prev_gdbarch; > + CORE_ADDR pc = 0; > + int pc_p = 0; > + > + /* The right way. The `pure' way. The one true way. This > + method depends solely on the register-unwind code to > + determine the value of registers in THIS frame, and hence > + the value of this frame's PC (resume address). A typical > + implementation is no more than: > + > + frame_unwind_register (this_frame, ISA_PC_REGNUM, buf); > + return extract_unsigned_integer (buf, size of ISA_PC_REGNUM); > + > + Note: this method is very heavily dependent on a correct > + register-unwind implementation, it pays to fix that > + method first; this method is frame type agnostic, since > + it only deals with register values, it works with any > + frame. This is all in stark contrast to the old > + FRAME_SAVED_PC which would try to directly handle all the > + different ways that a PC could be unwound. */ > + prev_gdbarch = frame_unwind_arch (this_frame); > + > + TRY > { > - struct gdbarch *prev_gdbarch; > - CORE_ADDR pc = 0; > - int pc_p = 0; > - > - /* The right way. The `pure' way. The one true way. This > - method depends solely on the register-unwind code to > - determine the value of registers in THIS frame, and hence > - the value of this frame's PC (resume address). A typical > - implementation is no more than: > - > - frame_unwind_register (this_frame, ISA_PC_REGNUM, buf); > - return extract_unsigned_integer (buf, size of ISA_PC_REGNUM); > - > - Note: this method is very heavily dependent on a correct > - register-unwind implementation, it pays to fix that > - method first; this method is frame type agnostic, since > - it only deals with register values, it works with any > - frame. This is all in stark contrast to the old > - FRAME_SAVED_PC which would try to directly handle all the > - different ways that a PC could be unwound. */ > - prev_gdbarch = frame_unwind_arch (this_frame); > - > - TRY > + pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); > + pc_p = 1; > + } > + CATCH (ex, RETURN_MASK_ERROR) > + { > + if (ex.error == NOT_AVAILABLE_ERROR) > { > - pc = gdbarch_unwind_pc (prev_gdbarch, this_frame); > - pc_p = 1; > + this_frame->prev_pc.status = CC_UNAVAILABLE; > + > + if (frame_debug) > + fprintf_unfiltered (gdb_stdlog, > + "{ frame_unwind_pc (this_frame=%d)" > + " -> }\n", > + this_frame->level); > } > - CATCH (ex, RETURN_MASK_ERROR) > + else if (ex.error == OPTIMIZED_OUT_ERROR) > { > - if (ex.error == NOT_AVAILABLE_ERROR) > - { > - this_frame->prev_pc.status = CC_UNAVAILABLE; > - > - if (frame_debug) > - fprintf_unfiltered (gdb_stdlog, > - "{ frame_unwind_pc (this_frame=%d)" > - " -> }\n", > - this_frame->level); > - } > - else if (ex.error == OPTIMIZED_OUT_ERROR) > - { > - this_frame->prev_pc.status = CC_NOT_SAVED; > - > - if (frame_debug) > - fprintf_unfiltered (gdb_stdlog, > - "{ frame_unwind_pc (this_frame=%d)" > - " -> }\n", > - this_frame->level); > - } > - else > - throw_exception (ex); > - } > - END_CATCH > + this_frame->prev_pc.status = CC_NOT_SAVED; > > - if (pc_p) > - { > - this_frame->prev_pc.value = pc; > - this_frame->prev_pc.status = CC_VALUE; > if (frame_debug) > fprintf_unfiltered (gdb_stdlog, > - "{ frame_unwind_pc (this_frame=%d) " > - "-> %s }\n", > - this_frame->level, > - hex_string (this_frame->prev_pc.value)); > + "{ frame_unwind_pc (this_frame=%d)" > + " -> }\n", > + this_frame->level); > } > + else > + throw_exception (ex); > + } > + END_CATCH > + > + if (pc_p) > + { > + this_frame->prev_pc.value = pc; > + this_frame->prev_pc.status = CC_VALUE; > + if (frame_debug) > + fprintf_unfiltered (gdb_stdlog, > + "{ frame_unwind_pc (this_frame=%d) " > + "-> %s }\n", > + this_frame->level, > + hex_string (this_frame->prev_pc.value)); > } > - else > - internal_error (__FILE__, __LINE__, _("No unwind_pc method")); > } > > if (this_frame->prev_pc.status == CC_VALUE) > @@ -2782,18 +2777,9 @@ get_frame_sp (struct frame_info *this_frame) > { > struct gdbarch *gdbarch = get_frame_arch (this_frame); > > - /* Normality - an architecture that provides a way of obtaining any > - frame inner-most address. */ > - if (gdbarch_unwind_sp_p (gdbarch)) > - /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to > - operate on THIS_FRAME now. */ > - return gdbarch_unwind_sp (gdbarch, this_frame->next); > - /* Now things are really are grim. Hope that the value returned by > - the gdbarch_sp_regnum register is meaningful. */ > - if (gdbarch_sp_regnum (gdbarch) >= 0) > - return get_frame_register_unsigned (this_frame, > - gdbarch_sp_regnum (gdbarch)); > - internal_error (__FILE__, __LINE__, _("Missing unwind SP method")); > + /* NOTE drow/2008-06-28: gdbarch_unwind_sp could be converted to > + operate on THIS_FRAME now. */ > + return gdbarch_unwind_sp (gdbarch, this_frame->next); > } > > /* Return the reason why we can't unwind past FRAME. */ > diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c > index e2abf263b3a..f65af109b2e 100644 > --- a/gdb/gdbarch.c > +++ b/gdb/gdbarch.c > @@ -48,6 +48,8 @@ > #include "regcache.h" > #include "objfiles.h" > #include "auxv.h" > +#include "frame-unwind.h" > +#include "dummy-frame.h" > > /* Static function declarations */ > > @@ -408,6 +410,7 @@ gdbarch_alloc (const struct gdbarch_info *info, > gdbarch->ecoff_reg_to_regnum = no_op_reg_to_regnum; > gdbarch->sdb_reg_to_regnum = no_op_reg_to_regnum; > gdbarch->dwarf2_reg_to_regnum = no_op_reg_to_regnum; > + gdbarch->dummy_id = default_dummy_id; > gdbarch->deprecated_fp_regnum = -1; > gdbarch->call_dummy_location = AT_ENTRY_POINT; > gdbarch->code_of_frame_writable = default_code_of_frame_writable; > @@ -427,6 +430,8 @@ gdbarch_alloc (const struct gdbarch_info *info, > gdbarch->memory_insert_breakpoint = default_memory_insert_breakpoint; > gdbarch->memory_remove_breakpoint = default_memory_remove_breakpoint; > gdbarch->remote_register_number = default_remote_register_number; > + gdbarch->unwind_pc = default_unwind_pc; > + gdbarch->unwind_sp = default_unwind_sp; > gdbarch->stabs_argument_has_addr = default_stabs_argument_has_addr; > gdbarch->convert_from_func_ptr_addr = convert_from_func_ptr_addr_identity; > gdbarch->addr_bits_remove = core_addr_identity; > @@ -570,7 +575,7 @@ verify_gdbarch (struct gdbarch *gdbarch) > if (gdbarch->register_name == 0) > log.puts ("\n\tregister_name"); > /* Skip verify of register_type, has predicate. */ > - /* Skip verify of dummy_id, has predicate. */ > + /* Skip verify of dummy_id, invalid_p == 0 */ > /* Skip verify of deprecated_fp_regnum, invalid_p == 0 */ > /* Skip verify of push_dummy_call, has predicate. */ > /* Skip verify of call_dummy_location, invalid_p == 0 */ > @@ -609,8 +614,8 @@ verify_gdbarch (struct gdbarch *gdbarch) > /* Skip verify of remote_register_number, invalid_p == 0 */ > /* Skip verify of fetch_tls_load_module_address, has predicate. */ > /* Skip verify of frame_args_skip, invalid_p == 0 */ > - /* Skip verify of unwind_pc, has predicate. */ > - /* Skip verify of unwind_sp, has predicate. */ > + /* Skip verify of unwind_pc, invalid_p == 0 */ > + /* Skip verify of unwind_sp, invalid_p == 0 */ > /* Skip verify of frame_num_args, has predicate. */ > /* Skip verify of frame_align, has predicate. */ > /* Skip verify of stabs_argument_has_addr, invalid_p == 0 */ > @@ -954,9 +959,6 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) > fprintf_unfiltered (file, > "gdbarch_dump: dtrace_probe_is_enabled = <%s>\n", > host_address_to_string (gdbarch->dtrace_probe_is_enabled)); > - fprintf_unfiltered (file, > - "gdbarch_dump: gdbarch_dummy_id_p() = %d\n", > - gdbarch_dummy_id_p (gdbarch)); > fprintf_unfiltered (file, > "gdbarch_dump: dummy_id = <%s>\n", > host_address_to_string (gdbarch->dummy_id)); > @@ -1440,15 +1442,9 @@ gdbarch_dump (struct gdbarch *gdbarch, struct ui_file *file) > fprintf_unfiltered (file, > "gdbarch_dump: type_align = <%s>\n", > host_address_to_string (gdbarch->type_align)); > - fprintf_unfiltered (file, > - "gdbarch_dump: gdbarch_unwind_pc_p() = %d\n", > - gdbarch_unwind_pc_p (gdbarch)); > fprintf_unfiltered (file, > "gdbarch_dump: unwind_pc = <%s>\n", > host_address_to_string (gdbarch->unwind_pc)); > - fprintf_unfiltered (file, > - "gdbarch_dump: gdbarch_unwind_sp_p() = %d\n", > - gdbarch_unwind_sp_p (gdbarch)); > fprintf_unfiltered (file, > "gdbarch_dump: unwind_sp = <%s>\n", > host_address_to_string (gdbarch->unwind_sp)); > @@ -2307,13 +2303,6 @@ set_gdbarch_register_type (struct gdbarch *gdbarch, > gdbarch->register_type = register_type; > } > > -int > -gdbarch_dummy_id_p (struct gdbarch *gdbarch) > -{ > - gdb_assert (gdbarch != NULL); > - return gdbarch->dummy_id != NULL; > -} > - > struct frame_id > gdbarch_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame) > { > @@ -3046,13 +3035,6 @@ set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, > gdbarch->frame_args_skip = frame_args_skip; > } > > -int > -gdbarch_unwind_pc_p (struct gdbarch *gdbarch) > -{ > - gdb_assert (gdbarch != NULL); > - return gdbarch->unwind_pc != NULL; > -} > - > CORE_ADDR > gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame) > { > @@ -3070,13 +3052,6 @@ set_gdbarch_unwind_pc (struct gdbarch *gdbarch, > gdbarch->unwind_pc = unwind_pc; > } > > -int > -gdbarch_unwind_sp_p (struct gdbarch *gdbarch) > -{ > - gdb_assert (gdbarch != NULL); > - return gdbarch->unwind_sp != NULL; > -} > - > CORE_ADDR > gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame) > { > diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h > index 2cb69610837..e8063922725 100644 > --- a/gdb/gdbarch.h > +++ b/gdb/gdbarch.h > @@ -380,8 +380,6 @@ typedef struct type * (gdbarch_register_type_ftype) (struct gdbarch *gdbarch, in > extern struct type * gdbarch_register_type (struct gdbarch *gdbarch, int reg_nr); > extern void set_gdbarch_register_type (struct gdbarch *gdbarch, gdbarch_register_type_ftype *register_type); > > -extern int gdbarch_dummy_id_p (struct gdbarch *gdbarch); > - > typedef struct frame_id (gdbarch_dummy_id_ftype) (struct gdbarch *gdbarch, struct frame_info *this_frame); > extern struct frame_id gdbarch_dummy_id (struct gdbarch *gdbarch, struct frame_info *this_frame); > extern void set_gdbarch_dummy_id (struct gdbarch *gdbarch, gdbarch_dummy_id_ftype *dummy_id); > @@ -622,14 +620,10 @@ extern void set_gdbarch_fetch_tls_load_module_address (struct gdbarch *gdbarch, > extern CORE_ADDR gdbarch_frame_args_skip (struct gdbarch *gdbarch); > extern void set_gdbarch_frame_args_skip (struct gdbarch *gdbarch, CORE_ADDR frame_args_skip); > > -extern int gdbarch_unwind_pc_p (struct gdbarch *gdbarch); > - > typedef CORE_ADDR (gdbarch_unwind_pc_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame); > extern CORE_ADDR gdbarch_unwind_pc (struct gdbarch *gdbarch, struct frame_info *next_frame); > extern void set_gdbarch_unwind_pc (struct gdbarch *gdbarch, gdbarch_unwind_pc_ftype *unwind_pc); > > -extern int gdbarch_unwind_sp_p (struct gdbarch *gdbarch); > - > typedef CORE_ADDR (gdbarch_unwind_sp_ftype) (struct gdbarch *gdbarch, struct frame_info *next_frame); > extern CORE_ADDR gdbarch_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame); > extern void set_gdbarch_unwind_sp (struct gdbarch *gdbarch, gdbarch_unwind_sp_ftype *unwind_sp); > diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh > index bbfa8d22058..96afb01c098 100755 > --- a/gdb/gdbarch.sh > +++ b/gdb/gdbarch.sh > @@ -480,7 +480,12 @@ m;const char *;register_name;int regnr;regnr;;0 > # use "register_type". > M;struct type *;register_type;int reg_nr;reg_nr > > -M;struct frame_id;dummy_id;struct frame_info *this_frame;this_frame > +# Generate a dummy frame_id for THIS_FRAME assuming that the frame is > +# a dummy frame. A dummy frame is created before an inferior call, > +# the frame_id returned here must match the base address returned by > +# gdbarch_push_dummy_call and the frame's pc must match the dummy > +# frames breakpoint address. > +m;struct frame_id;dummy_id;struct frame_info *this_frame;this_frame;;default_dummy_id;;0 > # Implement DUMMY_ID and PUSH_DUMMY_CALL, then delete > # deprecated_fp_regnum. > v;int;deprecated_fp_regnum;;;-1;-1;;0 > @@ -596,8 +601,8 @@ m;int;remote_register_number;int regno;regno;;default_remote_register_number;;0 > F;CORE_ADDR;fetch_tls_load_module_address;struct objfile *objfile;objfile > # > v;CORE_ADDR;frame_args_skip;;;0;;;0 > -M;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame > -M;CORE_ADDR;unwind_sp;struct frame_info *next_frame;next_frame > +m;CORE_ADDR;unwind_pc;struct frame_info *next_frame;next_frame;;default_unwind_pc;;0 > +m;CORE_ADDR;unwind_sp;struct frame_info *next_frame;next_frame;;default_unwind_sp;;0 > # DEPRECATED_FRAME_LOCALS_ADDRESS as been replaced by the per-frame > # frame-base. Enable frame-base before frame-unwind. > F;int;frame_num_args;struct frame_info *frame;frame > @@ -1670,6 +1675,8 @@ cat < #include "regcache.h" > #include "objfiles.h" > #include "auxv.h" > +#include "frame-unwind.h" > +#include "dummy-frame.h" > > /* Static function declarations */ > > -- > 2.14.5 >