On 2018-09-07 10:26 PM, Andrew Burgess wrote:
> This is a new version of the patch series that I original submitted
> here:
>
> https://sourceware.org/ml/gdb-patches/2018-03/msg00165.html
>
> That patch did get some feedback, which led to some revisions, the
> final version was posted here:
>
> https://sourceware.org/ml/gdb-patches/2018-06/msg00090.html
>
> However, this didn't get any feedback :-(
Sorry about that, my bad :(. For v2 and subsequent versions, I tend to let
the original reviewer do the follow-up. I forgot that this person was me.
> In this new version I have changed my approach. Rather than a series
> of patches, each supplying a new default gdbarch method and converting
> all targets, here I provide one patch that supplies just the new
> gdbarch methods, and converts no targets.
>
> No target should change once this patch is merged, as previously all
> the targets had to supply these methods themselves anyway.
>
> Once this patch is merged then I'll supply a series of patches based
> off of:
>
> https://sourceware.org/ml/gdb-patches/2018-06/msg00092.html
> https://sourceware.org/ml/gdb-patches/2018-06/msg00091.html
> https://sourceware.org/ml/gdb-patches/2018-06/msg00093.html
> https://sourceware.org/ml/gdb-patches/2018-06/msg00094.html
>
> that converts one target at a time to use the default gdbarch methods
> (where that is appropriate). I don't want to waste my time putting
> those patches together if I still can't get this patch in, but
> hopefully the above links should show you what my general intention
> is.
>
> All feedback welcome.
>
> 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.
>
> 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 | 16 +++++++
> gdb/dummy-frame.h | 6 +++
> gdb/frame-unwind.c | 31 +++++++++++++
> gdb/frame-unwind.h | 12 +++++
> gdb/frame.c | 132 ++++++++++++++++++++++++-----------------------------
> gdb/gdbarch.c | 41 ++++-------------
> gdb/gdbarch.h | 6 ---
> gdb/gdbarch.sh | 8 ++--
> 9 files changed, 154 insertions(+), 115 deletions(-)
>
> diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
> index c6f874a3b19..6bb128233d7 100644
> --- a/gdb/dummy-frame.c
> +++ b/gdb/dummy-frame.c
> @@ -385,6 +385,22 @@ const struct frame_unwind dummy_frame_unwind =
> dummy_frame_sniffer,
> };
>
> +/* Default implementation of gdbarch_dummy_id. Generate frame_id for
> + THIS_FRAME assuming that it 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. */
Use /* See dummy-frame.h. */
I think that additional info you have would be good in gdbarch.sh, to document
gdbarch_dummy_id.
> +
> +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..df2e5ddc6bd 100644
> --- a/gdb/frame-unwind.c
> +++ b/gdb/frame-unwind.c
> @@ -193,6 +193,37 @@ default_frame_unwind_stop_reason (struct frame_info *this_frame,
> return UNWIND_NO_REASON;
> }
>
> +/* Default unwind of the PC. */
Use /* See frame-unwind.h. */
> +
> +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);
It's up to you, but I'd declare the variables when assigning them (same for
all the new functions in this patch).
> +
> + release_value (value);
I'm not too familiar with the lifetime of struct value objects, but why is this
needed?
> + return addr;
> +}
> +
> +/* Default unwind of the SP. */
Use /* See frame-unwind.h. */
Thanks,
Simon
@@ -385,6 +385,22 @@ const struct frame_unwind dummy_frame_unwind =
dummy_frame_sniffer,
};
+/* Default implementation of gdbarch_dummy_id. Generate frame_id for
+ THIS_FRAME assuming that it 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. */
+
+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)
{
@@ -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) */
@@ -193,6 +193,37 @@ default_frame_unwind_stop_reason (struct frame_info *this_frame,
return UNWIND_NO_REASON;
}
+/* Default unwind of the PC. */
+
+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);
+ return addr;
+}
+
+/* Default unwind of the SP. */
+
+CORE_ADDR
+default_unwind_sp (struct gdbarch *gdbarch, struct frame_info *next_frame)
+{
+ int sp_regnum;
+
+ 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. */
@@ -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.
@@ -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)"
+ " -> <unavailable> }\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)"
- " -> <unavailable> }\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)"
- " -> <not saved> }\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)"
+ " -> <not saved> }\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. */
@@ -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)
{
@@ -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);
@@ -480,7 +480,7 @@ 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
+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 +596,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
@@ -1662,6 +1662,8 @@ cat <<EOF
#include "regcache.h"
#include "objfiles.h"
#include "auxv.h"
+#include "frame-unwind.h"
+#include "dummy-frame.h"
/* Static function declarations */