summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Cagney <cagney@redhat.com>2004-03-16 16:05:56 +0000
committerAndrew Cagney <cagney@redhat.com>2004-03-16 16:05:56 +0000
commit4cc7d9e9e76fff193f2623c5cb50aa0f97032e64 (patch)
treeea68d2b655758702c99ca9660d4cf391dfa47ab1
parent794ec6cc80ead2c363ebe5dcc93148185be1f82a (diff)
downloadgdb-4cc7d9e9e76fff193f2623c5cb50aa0f97032e64.tar.gz
Dump of tramp-frame stuff.
-rw-r--r--gdb/dummy-frame.c5
-rw-r--r--gdb/dummy-frame.h4
-rw-r--r--gdb/dwarf2-frame.c26
-rw-r--r--gdb/frame-base.c2
-rw-r--r--gdb/frame-unwind.c80
-rw-r--r--gdb/frame-unwind.h57
-rw-r--r--gdb/frame.c59
-rw-r--r--gdb/frame.h1
-rw-r--r--gdb/gdbarch.c50
-rw-r--r--gdb/gdbarch.h16
-rwxr-xr-xgdb/gdbarch.sh82
-rw-r--r--gdb/gnu-v3-abi.c2
-rw-r--r--gdb/ppc-linux-tdep.c148
-rw-r--r--gdb/regcache.c2
-rw-r--r--gdb/reggroups.c4
-rw-r--r--gdb/remote.c2
-rw-r--r--gdb/rs6000-tdep.c178
-rw-r--r--gdb/solib-svr4.c4
-rw-r--r--gdb/solib-svr4.h5
-rw-r--r--gdb/trad-frame.c105
-rw-r--r--gdb/trad-frame.h63
-rw-r--r--gdb/tramp-frame.c112
-rw-r--r--gdb/user-regs.c4
23 files changed, 617 insertions, 394 deletions
diff --git a/gdb/dummy-frame.c b/gdb/dummy-frame.c
index af9d957639f..f2e869a2471 100644
--- a/gdb/dummy-frame.c
+++ b/gdb/dummy-frame.c
@@ -403,7 +403,7 @@ dummy_frame_this_id (const struct frame_unwind *self,
(*this_id).stack_addr);
}
-static const struct frame_unwind dummy_frame_unwind =
+static struct frame_unwind dummy_frame_unwind =
{
DUMMY_FRAME,
dummy_frame_this_id,
@@ -411,8 +411,7 @@ static const struct frame_unwind dummy_frame_unwind =
};
const struct frame_unwind *
-dummy_frame_sniffer (const struct frame_unwind_sniffer *self,
- struct frame_info *next_frame)
+dummy_frame_sniffer (struct frame_info *next_frame)
{
CORE_ADDR pc = frame_pc_unwind (next_frame);
if (DEPRECATED_PC_IN_CALL_DUMMY_P ()
diff --git a/gdb/dummy-frame.h b/gdb/dummy-frame.h
index d095365c380..cde9eb7f12f 100644
--- a/gdb/dummy-frame.h
+++ b/gdb/dummy-frame.h
@@ -26,7 +26,6 @@ struct frame_info;
struct regcache;
struct frame_unwind;
struct frame_id;
-struct frame_unwind_sniffer;
/* GENERIC DUMMY FRAMES
@@ -49,8 +48,7 @@ struct frame_unwind_sniffer;
/* If the PC falls in a dummy frame, return a dummy frame
unwinder. */
-const struct frame_unwind *dummy_frame_sniffer (const struct frame_unwind_sniffer *self,
- struct frame_info *next_frame);
+extern const struct frame_unwind *dummy_frame_sniffer (struct frame_info *next_frame);
/* Does the PC fall in a dummy frame?
diff --git a/gdb/dwarf2-frame.c b/gdb/dwarf2-frame.c
index 27626084346..2b5ed32243b 100644
--- a/gdb/dwarf2-frame.c
+++ b/gdb/dwarf2-frame.c
@@ -509,29 +509,15 @@ dwarf2_frame_default_init_reg (struct gdbarch *gdbarch, int regnum,
/* Return a default for the architecture-specific operations. */
static void *
-dwarf2_frame_init (struct gdbarch *gdbarch)
+dwarf2_frame_init (struct obstack *obstack)
{
struct dwarf2_frame_ops *ops;
- ops = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct dwarf2_frame_ops);
+ ops = OBSTACK_ZALLOC (obstack, struct dwarf2_frame_ops);
ops->init_reg = dwarf2_frame_default_init_reg;
return ops;
}
-static struct dwarf2_frame_ops *
-dwarf2_frame_ops (struct gdbarch *gdbarch)
-{
- struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
- if (ops == NULL)
- {
- /* ULGH, called during architecture initialization. Patch
- things up. */
- ops = dwarf2_frame_init (gdbarch);
- set_gdbarch_data (gdbarch, dwarf2_frame_data, ops);
- }
- return ops;
-}
-
/* Set the architecture-specific register state initialization
function for GDBARCH to INIT_REG. */
@@ -540,9 +526,8 @@ dwarf2_frame_set_init_reg (struct gdbarch *gdbarch,
void (*init_reg) (struct gdbarch *, int,
struct dwarf2_frame_state_reg *))
{
- struct dwarf2_frame_ops *ops;
+ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
- ops = dwarf2_frame_ops (gdbarch);
ops->init_reg = init_reg;
}
@@ -552,9 +537,8 @@ static void
dwarf2_frame_init_reg (struct gdbarch *gdbarch, int regnum,
struct dwarf2_frame_state_reg *reg)
{
- struct dwarf2_frame_ops *ops;
+ struct dwarf2_frame_ops *ops = gdbarch_data (gdbarch, dwarf2_frame_data);
- ops = dwarf2_frame_ops (gdbarch);
ops->init_reg (gdbarch, regnum, reg);
}
@@ -1611,6 +1595,6 @@ void _initialize_dwarf2_frame (void);
void
_initialize_dwarf2_frame (void)
{
- dwarf2_frame_data = register_gdbarch_data (NULL, dwarf2_frame_init);
+ dwarf2_frame_data = gdbarch_data_register_pre_init (dwarf2_frame_init);
dwarf2_frame_objfile_data = register_objfile_data ();
}
diff --git a/gdb/frame-base.c b/gdb/frame-base.c
index 23ee681f311..80adb432e5f 100644
--- a/gdb/frame-base.c
+++ b/gdb/frame-base.c
@@ -152,5 +152,5 @@ extern initialize_file_ftype _initialize_frame_base; /* -Wmissing-prototypes */
void
_initialize_frame_base (void)
{
- frame_base_data = register_gdbarch_data (frame_base_init, NULL);
+ frame_base_data = gdbarch_data_register_pre_init (frame_base_init);
}
diff --git a/gdb/frame-unwind.c b/gdb/frame-unwind.c
index ee490c27124..f5f5dc1cf75 100644
--- a/gdb/frame-unwind.c
+++ b/gdb/frame-unwind.c
@@ -1,6 +1,6 @@
/* Definitions for frame unwinder, for GDB, the GNU debugger.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@@ -30,57 +30,50 @@ static struct gdbarch_data *frame_unwind_data;
struct frame_unwind_table_entry
{
- const struct frame_unwind_sniffer *sniffer;
+ frame_unwind_sniffer_ftype *sniffer;
+ const struct frame_unwind *unwinder;
struct frame_unwind_table_entry *next;
};
struct frame_unwind_table
{
- struct frame_unwind_table_entry *first;
+ struct frame_unwind_table_entry *head;
+ struct frame_unwind_table_entry **tail;
};
static void *
frame_unwind_init (struct obstack *obstack)
{
- struct frame_unwind_table *table;
- struct frame_unwind_sniffer *dummy_sniffer;
-
- dummy_sniffer = OBSTACK_ZALLOC (obstack, struct frame_unwind_sniffer);
- dummy_sniffer->sniffer = dummy_frame_sniffer;
-
- table = OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
- table->first = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
- table->first->sniffer = dummy_sniffer;
-
+ struct frame_unwind_table *table
+ = OBSTACK_ZALLOC (obstack, struct frame_unwind_table);
+ table->head = OBSTACK_ZALLOC (obstack, struct frame_unwind_table_entry);
+ table->head->sniffer = dummy_frame_sniffer;
+ table->tail = &table->head->next;
return table;
}
-/* Append a predicate to the end of the table. */
-
void
-frame_unwind_sniffer_append (struct gdbarch *gdbarch,
- const struct frame_unwind_sniffer *sniffer)
+frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+ frame_unwind_sniffer_ftype *sniffer)
{
struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
- struct frame_unwind_table_entry **entry;
- for (entry = &table->first; (*entry) != NULL; entry = &(*entry)->next);
- (*entry) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
- (*entry)->sniffer = sniffer;
+ (*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
+ (*table->tail)->sniffer = sniffer;
+ table->tail = &((*table->tail)->next);
}
void
-frame_unwind_append_sniffer (struct gdbarch *gdbarch,
- frame_unwind_sniffer_ftype *sniffer)
+frame_unwind_append (struct gdbarch *gdbarch,
+ const struct frame_unwind *unwinder)
{
- struct frame_unwind_sniffer *unwind_sniffer;
-
- unwind_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_sniffer);
- unwind_sniffer->sniffer = sniffer;
- frame_unwind_sniffer_append (gdbarch, unwind_sniffer);
+ struct frame_unwind_table *table = gdbarch_data (gdbarch, frame_unwind_data);
+ (*table->tail) = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_table_entry);
+ (*table->tail)->unwinder = unwinder;
+ table->tail = &((*table->tail)->next);
}
const struct frame_unwind *
-frame_unwind_find_by_frame (struct frame_info *next_frame)
+frame_unwind_find_by_frame (struct frame_info *next_frame, void **this_cache)
{
int i;
struct gdbarch *gdbarch = get_frame_arch (next_frame);
@@ -92,13 +85,28 @@ frame_unwind_find_by_frame (struct frame_info *next_frame)
the dummy frame mechanism. All architectures should be using
generic dummy frames). */
return legacy_saved_regs_unwind;
- for (entry = table->first; entry != NULL; entry = entry->next)
+ for (entry = table->head; entry != NULL; entry = entry->next)
{
- const struct frame_unwind *desc;
- gdb_assert (entry->sniffer->sniffer != NULL);
- desc = entry->sniffer->sniffer (entry->sniffer, next_frame);
- if (desc != NULL)
- return desc;
+ if (entry->sniffer != NULL)
+ {
+ const struct frame_unwind *desc = NULL;
+ desc = entry->sniffer (next_frame);
+ if (desc != NULL)
+ {
+ (*this_cache) = NULL;
+ return desc;
+ }
+ }
+ if (entry->unwinder != NULL)
+ {
+ void *cache = NULL;
+ cache = entry->unwinder->sniffer (entry->unwinder, next_frame);
+ if (cache != NULL)
+ {
+ (*this_cache) = cache;
+ return entry->unwinder;
+ }
+ }
}
return legacy_saved_regs_unwind;
}
@@ -108,5 +116,5 @@ extern initialize_file_ftype _initialize_frame_unwind; /* -Wmissing-prototypes *
void
_initialize_frame_unwind (void)
{
- frame_unwind_data = register_gdbarch_data (frame_unwind_init, NULL);
+ frame_unwind_data = gdbarch_data_register_pre_init (frame_unwind_init);
}
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index 89f1f2c5c6d..d29ea2b915c 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -1,6 +1,6 @@
/* Definitions for a frame unwinder, for GDB, the GNU debugger.
- Copyright 2003 Free Software Foundation, Inc.
+ Copyright 2003, 2004 Free Software Foundation, Inc.
This file is part of GDB.
@@ -22,6 +22,7 @@
#if !defined (FRAME_UNWIND_H)
#define FRAME_UNWIND_H 1
+struct frame_data;
struct frame_info;
struct frame_id;
struct frame_unwind;
@@ -30,6 +31,13 @@ struct regcache;
#include "frame.h" /* For enum frame_type. */
+/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
+ the PC and attributes) and if it is the applicable unwinder, return
+ an unwind cache (allocated using frame_obstack_zalloc). */
+
+typedef void *(frame_sniffer_ftype) (const struct frame_unwind *self,
+ struct frame_info *next_frame);
+
/* The following unwind functions assume a chain of frames forming the
sequence: (outer) prev <-> this <-> next (inner). All the
functions are called with called with the next frame's `struct
@@ -102,15 +110,14 @@ typedef void (frame_this_id_ftype) (const struct frame_unwind *self,
with the other unwind methods. Memory for that cache should be
allocated using frame_obstack_zalloc(). */
-typedef void (frame_prev_register_ftype)
- (const struct frame_unwind *self,
- struct frame_info *next_frame,
- void **this_prologue_cache,
- int prev_regnum,
- int *optimized,
- enum lval_type * lvalp,
- CORE_ADDR *addrp,
- int *realnump, void *valuep);
+typedef void (frame_prev_register_ftype) (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_prologue_cache,
+ int prev_regnum,
+ int *optimized,
+ enum lval_type * lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep);
struct frame_unwind
{
@@ -122,36 +129,32 @@ struct frame_unwind
frame_this_id_ftype *this_id;
frame_prev_register_ftype *prev_register;
const struct frame_data *unwind_data;
+ frame_sniffer_ftype *sniffer;
};
+/* Register a frame unwinder, appending it to the end of the search
+ list. */
+extern void frame_unwind_append (struct gdbarch *gdbarch,
+ const struct frame_unwind *unwinder);
+
+
/* Given the NEXT frame, take a wiff of THIS frame's registers (namely
the PC and attributes) and if it is the applicable unwinder return
the unwind methods, or NULL if it is not. */
-struct frame_unwind_sniffer;
-
-typedef const struct frame_unwind *(frame_unwind_sniffer_ftype)
- (const struct frame_unwind_sniffer *self,
- struct frame_info *next_frame);
-
-struct frame_unwind_sniffer
-{
- frame_unwind_sniffer_ftype *sniffer;
- const struct frame_data *sniffer_data;
-};
+typedef const struct frame_unwind *(frame_unwind_sniffer_ftype) (struct frame_info *next_frame);
/* Add a frame sniffer to the list. The predicates are polled in the
order that they are appended. The initial list contains the dummy
frame sniffer. */
-void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
- frame_unwind_sniffer_ftype *sniffer);
-void frame_unwind_sniffer_append (struct gdbarch *gdbarch,
- const struct frame_unwind_sniffer *sniffer);
+extern void frame_unwind_append_sniffer (struct gdbarch *gdbarch,
+ frame_unwind_sniffer_ftype *sniffer);
/* Iterate through the next frame's sniffers until one returns with an
- unwinder implementation. */
+ unwinder implementation. Possibly initialize THIS_CACHE. */
-extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame);
+extern const struct frame_unwind *frame_unwind_find_by_frame (struct frame_info *next_frame,
+ void **this_cache);
#endif
diff --git a/gdb/frame.c b/gdb/frame.c
index 18ae8c57cf7..b709cdb99b6 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -228,7 +228,8 @@ get_frame_id (struct frame_info *fi)
/* Find the unwinder. */
if (fi->unwind == NULL)
{
- fi->unwind = frame_unwind_find_by_frame (fi->next);
+ fi->unwind = frame_unwind_find_by_frame (fi->next,
+ &fi->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@@ -430,7 +431,7 @@ frame_pc_unwind (struct frame_info *this_frame)
}
CORE_ADDR
-frame_unwind_func_by_symtab (struct frame_info *fi)
+frame_func_unwind (struct frame_info *fi)
{
if (!fi->prev_func.p)
{
@@ -448,12 +449,6 @@ frame_unwind_func_by_symtab (struct frame_info *fi)
}
CORE_ADDR
-frame_func_unwind (struct frame_info *fi)
-{
- return frame_unwind_func_by_symtab (fi);
-}
-
-CORE_ADDR
get_frame_func (struct frame_info *fi)
{
return frame_func_unwind (fi->next);
@@ -539,7 +534,8 @@ frame_register_unwind (struct frame_info *frame, int regnum,
/* Find the unwinder. */
if (frame->unwind == NULL)
{
- frame->unwind = frame_unwind_find_by_frame (frame->next);
+ frame->unwind = frame_unwind_find_by_frame (frame->next,
+ &frame->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@@ -1201,7 +1197,7 @@ create_new_frame (CORE_ADDR addr, CORE_ADDR pc)
/* Select/initialize both the unwind function and the frame's type
based on the PC. */
- fi->unwind = frame_unwind_find_by_frame (fi->next);
+ fi->unwind = frame_unwind_find_by_frame (fi->next, &fi->prologue_cache);
if (fi->unwind->type != UNKNOWN_FRAME)
fi->type = fi->unwind->type;
else
@@ -1354,7 +1350,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
/* Set the unwind functions based on that identified PC. Ditto
for the "type" but strongly prefer the unwinder's frame type. */
- prev->unwind = frame_unwind_find_by_frame (prev->next);
+ prev->unwind = frame_unwind_find_by_frame (prev->next,
+ &prev->prologue_cache);
if (prev->unwind->type == UNKNOWN_FRAME)
prev->type = frame_type_from_pc (get_frame_pc (prev));
else
@@ -1454,8 +1451,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
/* Still don't want to worry about this except on the innermost
frame. This macro will set FROMLEAF if THIS_FRAME is a frameless
function invocation. */
- if (this_frame->level == 0
- && this_frame->unwind->type == UNKNOWN_FRAME)
+ if (this_frame->level == 0)
/* FIXME: 2002-11-09: Frameless functions can occure anywhere in
the frame chain, not just the inner most frame! The generic,
per-architecture, frame code should handle this and the below
@@ -1496,8 +1492,7 @@ legacy_get_prev_frame (struct frame_info *this_frame)
this to after the ffi test; I'd rather have backtraces from
start go curfluy than have an abort called from main not show
main. */
- if (DEPRECATED_FRAME_CHAIN_P ()
- && this_frame->unwind->type == UNKNOWN_FRAME)
+ if (DEPRECATED_FRAME_CHAIN_P ())
address = DEPRECATED_FRAME_CHAIN (this_frame);
else
{
@@ -1505,7 +1500,8 @@ legacy_get_prev_frame (struct frame_info *this_frame)
to the new frame code. Implement FRAME_CHAIN the way the
new frame will. */
/* Find PREV frame's unwinder. */
- prev->unwind = frame_unwind_find_by_frame (this_frame->next);
+ prev->unwind = frame_unwind_find_by_frame (this_frame->next,
+ &prev->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
@@ -1666,27 +1662,13 @@ legacy_get_prev_frame (struct frame_info *this_frame)
If there isn't a FRAME_CHAIN, the code above will have already
done this. */
if (prev->unwind == NULL)
- prev->unwind = frame_unwind_find_by_frame (prev->next);
+ prev->unwind = frame_unwind_find_by_frame (prev->next,
+ &prev->prologue_cache);
- /* If the unwinder provides a frame type (i.e., is a new style
- unwinder), use it. Otherwize continue on to that heuristic
- mess. */
- switch (prev->unwind->type)
+ /* If the unwinder provides a frame type, use it. Otherwize
+ continue on to that heuristic mess. */
+ if (prev->unwind->type != UNKNOWN_FRAME)
{
- case SIGTRAMP_FRAME:
- prev->type = prev->unwind->type;
- prev->unwind->this_id (prev->unwind, prev->next,
- &prev->prologue_cache,
- &prev->this_id.value);
- if (frame_debug)
- {
- fprintf_unfiltered (gdb_stdlog, "-> ");
- fprint_frame (gdb_stdlog, prev);
- fprintf_unfiltered (gdb_stdlog, " } // legacy with sigtramp type\n");
- }
- return prev;
- case DUMMY_FRAME:
- case NORMAL_FRAME:
prev->type = prev->unwind->type;
if (prev->type == NORMAL_FRAME)
/* FIXME: cagney/2003-06-16: would get_frame_pc() be better? */
@@ -1699,10 +1681,6 @@ legacy_get_prev_frame (struct frame_info *this_frame)
fprintf_unfiltered (gdb_stdlog, " } // legacy with unwound type\n");
}
return prev;
- case UNKNOWN_FRAME:
- break;
- default:
- internal_error (__FILE__, __LINE__, "bad switch");
}
/* NOTE: cagney/2002-11-18: The code segments, found in
@@ -2155,7 +2133,8 @@ get_frame_type (struct frame_info *frame)
{
/* Initialize the frame's unwinder because it is that which
provides the frame's type. */
- frame->unwind = frame_unwind_find_by_frame (frame->next);
+ frame->unwind = frame_unwind_find_by_frame (frame->next,
+ &frame->prologue_cache);
/* FIXME: cagney/2003-04-02: Rather than storing the frame's
type in the frame, the unwinder's type should be returned
directly. Unfortunately, legacy code, called by
diff --git a/gdb/frame.h b/gdb/frame.h
index b2e52b33fc7..0cdae6d31dc 100644
--- a/gdb/frame.h
+++ b/gdb/frame.h
@@ -260,7 +260,6 @@ extern CORE_ADDR frame_sp_unwind (struct frame_info *);
/* Following on from the `resume' address. Return the entry point
address of the function containing that resume address, or zero if
that function isn't known. */
-extern CORE_ADDR frame_unwind_func_by_symtab (struct frame_info *fi);
extern CORE_ADDR frame_func_unwind (struct frame_info *fi);
extern CORE_ADDR get_frame_func (struct frame_info *fi);
diff --git a/gdb/gdbarch.c b/gdb/gdbarch.c
index a8efa70e6f5..79279251446 100644
--- a/gdb/gdbarch.c
+++ b/gdb/gdbarch.c
@@ -5403,13 +5403,12 @@ struct gdbarch_data_registry gdbarch_data_registry =
0, NULL,
};
-struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_pre_init_ftype *pre_init,
+static struct gdbarch_data *
+gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
gdbarch_data_post_init_ftype *post_init)
{
struct gdbarch_data_registration **curr;
/* Append the new registraration. */
- gdb_assert ((pre_init != NULL) != (post_init != NULL));
for (curr = &gdbarch_data_registry.registrations;
(*curr) != NULL;
curr = &(*curr)->next);
@@ -5423,6 +5422,17 @@ register_gdbarch_data (gdbarch_data_pre_init_ftype *pre_init,
return (*curr)->data;
}
+struct gdbarch_data *
+gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
+{
+ return gdbarch_data_register (pre_init, NULL);
+}
+
+struct gdbarch_data *
+gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
+{
+ return gdbarch_data_register (NULL, post_init);
+}
/* Create/delete the gdbarch data vector. */
@@ -5438,12 +5448,13 @@ alloc_gdbarch_data (struct gdbarch *gdbarch)
data-pointer. */
void
-set_gdbarch_data (struct gdbarch *gdbarch,
- struct gdbarch_data *data,
- void *pointer)
+deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
{
gdb_assert (data->index < gdbarch->nr_data);
gdb_assert (gdbarch->data[data->index] == NULL);
+ gdb_assert (data->pre_init == NULL);
gdbarch->data[data->index] = pointer;
}
@@ -5456,23 +5467,38 @@ gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
gdb_assert (data->index < gdbarch->nr_data);
if (gdbarch->data[data->index] == NULL)
{
- /* Be careful to detect an initialization cycle. */
- gdb_assert (data->init_p);
- data->init_p = 0;
+ /* The data-pointer isn't initialized, call init() to get a
+ value. */
if (data->pre_init != NULL)
+ /* Mid architecture creation: pass just the obstack, and not
+ the entire architecture, as that way it isn't possible for
+ pre-init code to refer to undefined architecture
+ fields. */
gdbarch->data[data->index] = data->pre_init (gdbarch->obstack);
else if (gdbarch->initialized_p
&& data->post_init != NULL)
- gdbarch->data[data->index] = data->post_init (gdbarch);
+ /* Post architecture creation: pass the entire architecture
+ (as all fields are valid), but be careful to also detect
+ recursive references. */
+ {
+ gdb_assert (data->init_p);
+ data->init_p = 0;
+ gdbarch->data[data->index] = data->post_init (gdbarch);
+ data->init_p = 1;
+ }
else
- internal_error (__FILE__, __LINE__, "Bad initialization method");
- data->init_p = 1;
+ /* The architecture initialization hasn't completed - punt -
+ hope that the caller knows what they are doing. Once
+ deprecated_set_gdbarch_data has been initialized, this can be
+ changed to an internal error. */
+ return NULL;
gdb_assert (gdbarch->data[data->index] != NULL);
}
return gdbarch->data[data->index];
}
+
/* Keep a registry of swapped data required by GDB modules. */
struct gdbarch_swap
diff --git a/gdb/gdbarch.h b/gdb/gdbarch.h
index 84e5c5cd275..2280cfad197 100644
--- a/gdb/gdbarch.h
+++ b/gdb/gdbarch.h
@@ -2518,10 +2518,6 @@ extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch);
for the reserved data-pointer is returned. That identifer should
be saved in a local static variable.
- The per-architecture data-pointer is either initialized explicitly
- (set_gdbarch_data()) or implicitly (by INIT() via a call to
- gdbarch_data()).
-
Memory for the per-architecture data shall be allocated using
gdbarch_obstack_zalloc. That memory will be deleted when the
corresponding architecture object is deleted.
@@ -2536,12 +2532,12 @@ extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch);
struct gdbarch_data;
typedef void *(gdbarch_data_pre_init_ftype) (struct obstack *obstack);
+extern struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *init);
typedef void *(gdbarch_data_post_init_ftype) (struct gdbarch *gdbarch);
-extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_pre_init_ftype *pre,
- gdbarch_data_post_init_ftype *post);
-extern void set_gdbarch_data (struct gdbarch *gdbarch,
- struct gdbarch_data *data,
- void *pointer);
+extern struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *init);
+extern void deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer);
extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
@@ -2557,7 +2553,7 @@ extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
Memory regions are swapped / initialized in the order that they are
registered. NULL DATA and/or INIT values can be specified.
- New code should use register_gdbarch_data(). */
+ New code should use gdbarch_data_register_*(). */
typedef void (gdbarch_swap_ftype) (void);
extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
diff --git a/gdb/gdbarch.sh b/gdb/gdbarch.sh
index fab9fdef3e2..f5d6b056917 100755
--- a/gdb/gdbarch.sh
+++ b/gdb/gdbarch.sh
@@ -1202,10 +1202,6 @@ extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch);
for the reserved data-pointer is returned. That identifer should
be saved in a local static variable.
- The per-architecture data-pointer is either initialized explicitly
- (set_gdbarch_data()) or implicitly (by INIT() via a call to
- gdbarch_data()).
-
Memory for the per-architecture data shall be allocated using
gdbarch_obstack_zalloc. That memory will be deleted when the
corresponding architecture object is deleted.
@@ -1220,12 +1216,12 @@ extern void deprecated_current_gdbarch_select_hack (struct gdbarch *gdbarch);
struct gdbarch_data;
typedef void *(gdbarch_data_pre_init_ftype) (struct obstack *obstack);
+extern struct gdbarch_data *gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *init);
typedef void *(gdbarch_data_post_init_ftype) (struct gdbarch *gdbarch);
-extern struct gdbarch_data *register_gdbarch_data (gdbarch_data_pre_init_ftype *pre,
- gdbarch_data_post_init_ftype *post);
-extern void set_gdbarch_data (struct gdbarch *gdbarch,
- struct gdbarch_data *data,
- void *pointer);
+extern struct gdbarch_data *gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *init);
+extern void deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer);
extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
@@ -1241,7 +1237,7 @@ extern void *gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *);
Memory regions are swapped / initialized in the order that they are
registered. NULL DATA and/or INIT values can be specified.
- New code should use register_gdbarch_data(). */
+ New code should use gdbarch_data_register_*(). */
typedef void (gdbarch_swap_ftype) (void);
extern void deprecated_register_gdbarch_swap (void *data, unsigned long size, gdbarch_swap_ftype *init);
@@ -1814,7 +1810,8 @@ struct gdbarch_data
{
unsigned index;
int init_p;
- gdbarch_data_init_ftype *init;
+ gdbarch_data_pre_init_ftype *pre_init;
+ gdbarch_data_post_init_ftype *post_init;
};
struct gdbarch_data_registration
@@ -1834,8 +1831,9 @@ struct gdbarch_data_registry gdbarch_data_registry =
0, NULL,
};
-struct gdbarch_data *
-register_gdbarch_data (gdbarch_data_init_ftype *init)
+static struct gdbarch_data *
+gdbarch_data_register (gdbarch_data_pre_init_ftype *pre_init,
+ gdbarch_data_post_init_ftype *post_init)
{
struct gdbarch_data_registration **curr;
/* Append the new registraration. */
@@ -1846,11 +1844,23 @@ register_gdbarch_data (gdbarch_data_init_ftype *init)
(*curr)->next = NULL;
(*curr)->data = XMALLOC (struct gdbarch_data);
(*curr)->data->index = gdbarch_data_registry.nr++;
- (*curr)->data->init = init;
+ (*curr)->data->pre_init = pre_init;
+ (*curr)->data->post_init = post_init;
(*curr)->data->init_p = 1;
return (*curr)->data;
}
+struct gdbarch_data *
+gdbarch_data_register_pre_init (gdbarch_data_pre_init_ftype *pre_init)
+{
+ return gdbarch_data_register (pre_init, NULL);
+}
+
+struct gdbarch_data *
+gdbarch_data_register_post_init (gdbarch_data_post_init_ftype *post_init)
+{
+ return gdbarch_data_register (NULL, post_init);
+}
/* Create/delete the gdbarch data vector. */
@@ -1866,12 +1876,13 @@ alloc_gdbarch_data (struct gdbarch *gdbarch)
data-pointer. */
void
-set_gdbarch_data (struct gdbarch *gdbarch,
- struct gdbarch_data *data,
- void *pointer)
+deprecated_set_gdbarch_data (struct gdbarch *gdbarch,
+ struct gdbarch_data *data,
+ void *pointer)
{
gdb_assert (data->index < gdbarch->nr_data);
gdb_assert (gdbarch->data[data->index] == NULL);
+ gdb_assert (data->pre_init == NULL);
gdbarch->data[data->index] = pointer;
}
@@ -1882,18 +1893,33 @@ void *
gdbarch_data (struct gdbarch *gdbarch, struct gdbarch_data *data)
{
gdb_assert (data->index < gdbarch->nr_data);
- /* The data-pointer isn't initialized, call init() to get a value but
- only if the architecture initializaiton has completed. Otherwise
- punt - hope that the caller knows what they are doing. */
- if (gdbarch->data[data->index] == NULL
- && gdbarch->initialized_p)
+ if (gdbarch->data[data->index] == NULL)
{
- /* Be careful to detect an initialization cycle. */
- gdb_assert (data->init_p);
- data->init_p = 0;
- gdb_assert (data->init != NULL);
- gdbarch->data[data->index] = data->init (gdbarch);
- data->init_p = 1;
+ /* The data-pointer isn't initialized, call init() to get a
+ value. */
+ if (data->pre_init != NULL)
+ /* Mid architecture creation: pass just the obstack, and not
+ the entire architecture, as that way it isn't possible for
+ pre-init code to refer to undefined architecture
+ fields. */
+ gdbarch->data[data->index] = data->pre_init (gdbarch->obstack);
+ else if (gdbarch->initialized_p
+ && data->post_init != NULL)
+ /* Post architecture creation: pass the entire architecture
+ (as all fields are valid), but be careful to also detect
+ recursive references. */
+ {
+ gdb_assert (data->init_p);
+ data->init_p = 0;
+ gdbarch->data[data->index] = data->post_init (gdbarch);
+ data->init_p = 1;
+ }
+ else
+ /* The architecture initialization hasn't completed - punt -
+ hope that the caller knows what they are doing. Once
+ deprecated_set_gdbarch_data has been initialized, this can be
+ changed to an internal error. */
+ return NULL;
gdb_assert (gdbarch->data[data->index] != NULL);
}
return gdbarch->data[data->index];
diff --git a/gdb/gnu-v3-abi.c b/gdb/gnu-v3-abi.c
index bcaf68f8b0f..195af26400b 100644
--- a/gdb/gnu-v3-abi.c
+++ b/gdb/gnu-v3-abi.c
@@ -422,7 +422,7 @@ gnuv3_baseclass_offset (struct type *type, int index, char *valaddr,
static void
init_gnuv3_ops (void)
{
- vtable_type_gdbarch_data = register_gdbarch_data (NULL, build_gdb_vtable_type);
+ vtable_type_gdbarch_data = gdbarch_data_register_post_init (build_gdb_vtable_type);
gnu_v3_abi_ops.shortname = "gnu-v3";
gnu_v3_abi_ops.longname = "GNU G++ Version 3 ABI";
diff --git a/gdb/ppc-linux-tdep.c b/gdb/ppc-linux-tdep.c
index 84eb742d8e2..08f2d644b28 100644
--- a/gdb/ppc-linux-tdep.c
+++ b/gdb/ppc-linux-tdep.c
@@ -32,7 +32,8 @@
#include "regcache.h"
#include "value.h"
#include "osabi.h"
-
+#include "trad-frame.h"
+#include "tramp-frame.h"
#include "solib-svr4.h"
#include "ppc-tdep.h"
@@ -1035,6 +1036,144 @@ static struct core_fns ppc_linux_regset_core_fns =
};
static void
+ppc_linux_sigtramp_cache (struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func, LONGEST offset,
+ int bias)
+{
+ CORE_ADDR base;
+ CORE_ADDR regs;
+ CORE_ADDR gpregs;
+ CORE_ADDR fpregs;
+ int i;
+ struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
+
+ base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+ if (bias > 0 && frame_pc_unwind (next_frame) != func)
+ /* See below, some signal trampolines increment the stack as their
+ first instruction, need to compensate for that. */
+ base -= bias;
+
+ /* Find the address of the register buffer pointer. */
+ regs = base + offset;
+ /* Use that to find the address of the corresponding register
+ buffers. */
+ gpregs = read_memory_unsigned_integer (regs, tdep->wordsize);
+ fpregs = gpregs + 48 * tdep->wordsize;
+
+ /* General purpose. */
+ for (i = 0; i < 32; i++)
+ {
+ int regnum = i + tdep->ppc_gp0_regnum;
+ trad_frame_set_addr (this_cache, regnum, gpregs + i * tdep->wordsize);
+ }
+ trad_frame_set_addr (this_cache, PC_REGNUM, gpregs + 32 * tdep->wordsize);
+ trad_frame_set_addr (this_cache, tdep->ppc_ctr_regnum,
+ gpregs + 35 * tdep->wordsize);
+ trad_frame_set_addr (this_cache, tdep->ppc_lr_regnum,
+ gpregs + 36 * tdep->wordsize);
+ trad_frame_set_addr (this_cache, tdep->ppc_xer_regnum,
+ gpregs + 37 * tdep->wordsize);
+ trad_frame_set_addr (this_cache, tdep->ppc_cr_regnum,
+ gpregs + 38 * tdep->wordsize);
+
+ /* Floating point registers. */
+ for (i = 0; i < 32; i++)
+ {
+ int regnum = i + FP0_REGNUM;
+ trad_frame_set_addr (this_cache, regnum, fpregs + i * tdep->wordsize);
+ }
+ trad_frame_set_addr (this_cache, tdep->ppc_fpscr_regnum,
+ fpregs + 32 * tdep->wordsize);
+
+ this_cache->this_id = frame_id_build (base, func);
+}
+
+static void
+ppc32_linux_sigaction_cache_init (const struct tramp_frame *self,
+ struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+ 0xd0 /* Offset to ucontext_t. */
+ + 0x30 /* Offset to .reg. */,
+ 0);
+}
+
+static void
+ppc64_linux_sigaction_cache_init (const struct tramp_frame *self,
+ struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+ 0x80 /* Offset to ucontext_t. */
+ + 0xe0 /* Offset to .reg. */,
+ 128);
+}
+
+static void
+ppc32_linux_sighandler_cache_init (const struct tramp_frame *self,
+ struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+ 0x40 /* Offset to ucontext_t. */
+ + 0x1c /* Offset to .reg. */,
+ 0);
+}
+
+static void
+ppc64_linux_sighandler_cache_init (const struct tramp_frame *self,
+ struct frame_info *next_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
+{
+ ppc_linux_sigtramp_cache (next_frame, this_cache, func,
+ 0x80 /* Offset to struct sigcontext. */
+ + 0x38 /* Offset to .reg. */,
+ 128);
+}
+
+static struct tramp_frame ppc32_linux_sigaction_tramp_frame = {
+ 4,
+ { 0x380000ac, /* li r0, 172 */
+ 0x44000002, /* sc */
+ 0
+ },
+ ppc32_linux_sigaction_cache_init
+};
+static struct tramp_frame ppc64_linux_sigaction_tramp_frame = {
+ 4,
+ { 0x38210080, /* addi r1,r1,128 */
+ 0x380000ac, /* li r0, 172 */
+ 0x44000002, /* sc */
+ 0
+ },
+ ppc64_linux_sigaction_cache_init
+};
+static struct tramp_frame ppc32_linux_sighandler_tramp_frame = {
+ 4,
+ { 0x38000077, /* li r0,119 */
+ 0x44000002, /* sc */
+ 0
+ },
+ ppc32_linux_sighandler_cache_init
+};
+static struct tramp_frame ppc64_linux_sighandler_tramp_frame = {
+ 4,
+ { 0x38210080, /* addi r1,r1,128 */
+ 0x38000077, /* li r0,119 */
+ 0x44000002, /* sc */
+ 0
+ },
+ ppc64_linux_sighandler_cache_init
+};
+
+static void
ppc_linux_init_abi (struct gdbarch_info info,
struct gdbarch *gdbarch)
{
@@ -1070,6 +1209,10 @@ ppc_linux_init_abi (struct gdbarch_info info,
ppc_linux_skip_trampoline_code);
set_solib_svr4_fetch_link_map_offsets
(gdbarch, ppc_linux_svr4_fetch_link_map_offsets);
+
+ /* Trampolines. */
+ tramp_frame_append (gdbarch, &ppc32_linux_sigaction_tramp_frame);
+ tramp_frame_append (gdbarch, &ppc32_linux_sighandler_tramp_frame);
}
if (tdep->wordsize == 8)
@@ -1085,6 +1228,9 @@ ppc_linux_init_abi (struct gdbarch_info info,
/* PPC64 malloc's entry-point is called ".malloc". */
set_gdbarch_name_of_malloc (gdbarch, ".malloc");
+
+ tramp_frame_append (gdbarch, &ppc64_linux_sigaction_tramp_frame);
+ tramp_frame_append (gdbarch, &ppc64_linux_sighandler_tramp_frame);
}
}
diff --git a/gdb/regcache.c b/gdb/regcache.c
index eaa56868ef5..c455e46690e 100644
--- a/gdb/regcache.c
+++ b/gdb/regcache.c
@@ -1705,7 +1705,7 @@ extern initialize_file_ftype _initialize_regcache; /* -Wmissing-prototype */
void
_initialize_regcache (void)
{
- regcache_descr_handle = register_gdbarch_data (NULL, init_regcache_descr);
+ regcache_descr_handle = gdbarch_data_register_post_init (init_regcache_descr);
DEPRECATED_REGISTER_GDBARCH_SWAP (current_regcache);
DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_registers);
DEPRECATED_REGISTER_GDBARCH_SWAP (deprecated_register_valid);
diff --git a/gdb/reggroups.c b/gdb/reggroups.c
index 79cb9fb8d83..c20f886a33e 100644
--- a/gdb/reggroups.c
+++ b/gdb/reggroups.c
@@ -109,7 +109,7 @@ reggroup_add (struct gdbarch *gdbarch, struct reggroup *group)
/* ULGH, called during architecture initialization. Patch
things up. */
groups = reggroups_init (gdbarch);
- set_gdbarch_data (gdbarch, reggroups_data, groups);
+ deprecated_set_gdbarch_data (gdbarch, reggroups_data, groups);
}
add_group (groups, group,
GDBARCH_OBSTACK_ZALLOC (gdbarch, struct reggroup_el));
@@ -268,7 +268,7 @@ extern initialize_file_ftype _initialize_reggroup; /* -Wmissing-prototypes */
void
_initialize_reggroup (void)
{
- reggroups_data = register_gdbarch_data (NULL, reggroups_init);
+ reggroups_data = gdbarch_data_register_post_init (reggroups_init);
/* The pre-defined list of groups. */
add_group (&default_groups, general_reggroup, XMALLOC (struct reggroup_el));
diff --git a/gdb/remote.c b/gdb/remote.c
index 45da70d62eb..a5cb2190a1f 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -5456,7 +5456,7 @@ _initialize_remote (void)
struct cmd_list_element *tmpcmd;
/* architecture specific data */
- remote_gdbarch_data_handle = register_gdbarch_data (NULL, init_remote_state);
+ remote_gdbarch_data_handle = gdbarch_data_register_post_init (init_remote_state);
/* Old tacky stuff. NOTE: This comes after the remote protocol so
that the remote protocol has been initialized. */
diff --git a/gdb/rs6000-tdep.c b/gdb/rs6000-tdep.c
index 26a6f37826b..6117b8231ad 100644
--- a/gdb/rs6000-tdep.c
+++ b/gdb/rs6000-tdep.c
@@ -69,7 +69,6 @@
struct rs6000_framedata
{
- CORE_ADDR func_start; /* true function start */
int offset; /* total size of frame --- the distance
by which we decrement sp to allocate
the frame */
@@ -507,7 +506,6 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
int minimal_toc_loaded = 0;
int prev_insn_was_prologue_insn = 1;
int num_skip_non_prologue_insns = 0;
- int num_skip_syscall_insn = 0;
const struct bfd_arch_info *arch_info = gdbarch_bfd_arch_info (current_gdbarch);
struct gdbarch_tdep *tdep = gdbarch_tdep (current_gdbarch);
@@ -527,7 +525,6 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
lim_pc = refine_prologue_limit (pc, lim_pc);
memset (fdata, 0, sizeof (struct rs6000_framedata));
- fdata->func_start = pc;
fdata->saved_gpr = -1;
fdata->saved_fpr = -1;
fdata->saved_vr = -1;
@@ -556,65 +553,9 @@ skip_prologue (CORE_ADDR pc, CORE_ADDR lim_pc, struct rs6000_framedata *fdata)
break;
op = extract_signed_integer (buf, 4);
- /* A PPC64 GNU/Linux system call function starts with a
- non-threaded fast-path, only when that fails is a stack frame
- created, treat it as several functions:
-
- *INDENT-OFF*
- NAME:
- SINGLE_THREAD_P
- bne- .Lpseudo_cancel
- __NAME_nocancel:
- li r0,162
- sc
- bnslr+
- b 0x7fe014ef64 <.__syscall_error>
- Lpseudo_cancel:
- stdu r1,-128(r1)
- ...
- *INDENT-ON* */
- if (((op & 0xffff0000) == 0x38000000 /* li r0,N */
- && pc == fdata->func + 0)
- || (op == 0x44000002 /* sc */
- && pc == fdata->func + 4
- && num_skip_syscall_insn == 1)
- || (op == 0x4ca30020 /* bnslr+ */
- && pc == fdata->func + 8
- && num_skip_syscall_insn == 2))
- {
- num_skip_syscall_insn++;
- continue;
- }
- else if ((op & 0xfc000003) == 0x48000000 /* b __syscall_error */
- && pc == fdata->func + 12
- && num_skip_syscall_insn == 3)
- {
- num_skip_syscall_insn++;
- fdata->func_start = pc;
- continue;
- }
-
if ((op & 0xfc1fffff) == 0x7c0802a6)
{ /* mflr Rx */
- /* Since shared library / PIC code, which needs to get its
- address at runtime, can appear to save more than one link
- register vis:
-
- *INDENT-OFF*
- stwu r1,-304(r1)
- mflr r3
- bl 0xff570d0 (blrl)
- stw r30,296(r1)
- mflr r30
- stw r31,300(r1)
- stw r3,308(r1);
- ...
- *INDENT-ON*
-
- remember just the first one, but skip over additional
- ones. */
- if (lr_reg < 0)
- lr_reg = (op & 0x03e00000);
+ lr_reg = (op & 0x03e00000);
continue;
}
@@ -1925,12 +1866,12 @@ rs6000_register_virtual_type (int n)
case 0:
return builtin_type_int0;
case 4:
- return builtin_type_uint32;
+ return builtin_type_int32;
case 8:
if (tdep->ppc_ev0_regnum <= n && n <= tdep->ppc_ev31_regnum)
return builtin_type_vec64;
else
- return builtin_type_uint64;
+ return builtin_type_int64;
break;
case 16:
return builtin_type_vec128;
@@ -2699,19 +2640,23 @@ rs6000_unwind_dummy_id (struct gdbarch *gdbarch, struct frame_info *next_frame)
frame_pc_unwind (next_frame));
}
-static void
-rs6000_trad_frame_init (const struct trad_frame *self,
- struct frame_info *next_frame,
- struct trad_frame_cache *this_cache)
+static struct trad_frame_cache *
+rs6000_frame_cache (struct frame_info *next_frame, void **this_cache)
{
+ struct trad_frame_cache *cache;
struct gdbarch *gdbarch = get_frame_arch (next_frame);
struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
struct rs6000_framedata fdata;
- CORE_ADDR base;
int wordsize = tdep->wordsize;
+ CORE_ADDR base;
+
+ if ((*this_cache) != NULL)
+ return (*this_cache);
+ cache = trad_frame_cache_zalloc (next_frame);
+ (*this_cache) = cache;
- skip_prologue (frame_unwind_func_by_symtab (next_frame),
- frame_pc_unwind (next_frame), &fdata);
+ skip_prologue (frame_func_unwind (next_frame), frame_pc_unwind (next_frame),
+ &fdata);
/* If there were any saved registers, figure out parent's stack
pointer. */
@@ -2739,7 +2684,7 @@ rs6000_trad_frame_init (const struct trad_frame *self,
/* Frameless really means stackless. */
base = read_memory_addr (base, wordsize);
}
- trad_frame_set_value (this_cache, SP_REGNUM, base);
+ trad_frame_set_reg_value (cache, SP_REGNUM, base);
/* if != -1, fdata.saved_fpr is the smallest number of saved_fpr.
All fpr's from saved_fpr to fp31 are saved. */
@@ -2750,7 +2695,7 @@ rs6000_trad_frame_init (const struct trad_frame *self,
CORE_ADDR fpr_addr = base + fdata.fpr_offset;
for (i = fdata.saved_fpr; i < 32; i++)
{
- this_cache->prev_regs[FP0_REGNUM + i].addr = fpr_addr;
+ cache->saved_regs[FP0_REGNUM + i].addr = fpr_addr;
fpr_addr += 8;
}
}
@@ -2764,7 +2709,7 @@ rs6000_trad_frame_init (const struct trad_frame *self,
CORE_ADDR gpr_addr = base + fdata.gpr_offset;
for (i = fdata.saved_gpr; i < 32; i++)
{
- this_cache->prev_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
+ cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = gpr_addr;
gpr_addr += wordsize;
}
}
@@ -2779,7 +2724,7 @@ rs6000_trad_frame_init (const struct trad_frame *self,
CORE_ADDR vr_addr = base + fdata.vr_offset;
for (i = fdata.saved_vr; i < 32; i++)
{
- this_cache->prev_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
+ cache->saved_regs[tdep->ppc_vr0_regnum + i].addr = vr_addr;
vr_addr += register_size (gdbarch, tdep->ppc_vr0_regnum);
}
}
@@ -2795,8 +2740,8 @@ rs6000_trad_frame_init (const struct trad_frame *self,
CORE_ADDR ev_addr = base + fdata.ev_offset;
for (i = fdata.saved_ev; i < 32; i++)
{
- this_cache->prev_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr;
- this_cache->prev_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + 4;
+ cache->saved_regs[tdep->ppc_ev0_regnum + i].addr = ev_addr;
+ cache->saved_regs[tdep->ppc_gp0_regnum + i].addr = ev_addr + 4;
ev_addr += register_size (gdbarch, tdep->ppc_ev0_regnum);
}
}
@@ -2805,43 +2750,95 @@ rs6000_trad_frame_init (const struct trad_frame *self,
/* If != 0, fdata.cr_offset is the offset from the frame that
holds the CR. */
if (fdata.cr_offset != 0)
- this_cache->prev_regs[tdep->ppc_cr_regnum].addr = base + fdata.cr_offset;
+ cache->saved_regs[tdep->ppc_cr_regnum].addr = base + fdata.cr_offset;
/* If != 0, fdata.lr_offset is the offset from the frame that
holds the LR. */
if (fdata.lr_offset != 0)
- this_cache->prev_regs[tdep->ppc_lr_regnum].addr = base + fdata.lr_offset;
+ cache->saved_regs[tdep->ppc_lr_regnum].addr = base + fdata.lr_offset;
/* The PC is found in the link register. */
- this_cache->prev_regs[PC_REGNUM] = this_cache->prev_regs[tdep->ppc_lr_regnum];
+ cache->saved_regs[PC_REGNUM] = cache->saved_regs[tdep->ppc_lr_regnum];
/* If != 0, fdata.vrsave_offset is the offset from the frame that
holds the VRSAVE. */
if (fdata.vrsave_offset != 0)
- this_cache->prev_regs[tdep->ppc_vrsave_regnum].addr = base + fdata.vrsave_offset;
+ cache->saved_regs[tdep->ppc_vrsave_regnum].addr = base + fdata.vrsave_offset;
if (fdata.alloca_reg < 0)
/* If no alloca register used, then fi->frame is the value of the
%sp for this frame, and it is good enough. */
- this_cache->this_base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
+ cache->this_base = frame_unwind_register_unsigned (next_frame, SP_REGNUM);
else
- this_cache->this_base = frame_unwind_register_unsigned (next_frame,
+ cache->this_base = frame_unwind_register_unsigned (next_frame,
fdata.alloca_reg);
- this_cache->this_id = frame_id_build (base, fdata.func);
+
+ cache->this_id = frame_id_build (base, frame_func_unwind (next_frame));
+
+ return cache;
}
-static int
-rs6000_trad_frame_sniffer (const struct trad_frame *self,
- struct frame_info *next_frame)
+static void
+rs6000_frame_this_id (const struct frame_unwind *self,
+ struct frame_info *next_frame, void **this_cache,
+ struct frame_id *this_id)
{
- return 1;
+ struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+ this_cache);
+ trad_frame_this_id (trad_cache, next_frame, this_id);
}
-struct trad_frame rs6000_trad_frame = {
+static void
+rs6000_frame_prev_register (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_cache,
+ int regnum, int *optimizedp,
+ enum lval_type *lvalp, CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+ this_cache);
+ trad_frame_prev_register (trad_cache, next_frame, regnum,
+ optimizedp, lvalp, addrp, realnump, valuep);
+}
+
+static const struct frame_unwind rs6000_frame_unwind =
+{
NORMAL_FRAME,
- rs6000_trad_frame_sniffer,
- rs6000_trad_frame_init,
+ rs6000_frame_this_id,
+ rs6000_frame_prev_register
};
+static const struct frame_unwind *
+rs6000_frame_sniffer (struct frame_info *next_frame)
+{
+ return &rs6000_frame_unwind;
+}
+
+
+
+static CORE_ADDR
+rs6000_frame_base_address (const struct frame_base *self,
+ struct frame_info *next_frame,
+ void **this_cache)
+{
+ struct trad_frame_cache *trad_cache = rs6000_frame_cache (next_frame,
+ this_cache);
+ return trad_cache->this_base;
+}
+
+static const struct frame_base rs6000_frame_base = {
+ &rs6000_frame_unwind,
+ rs6000_frame_base_address,
+ rs6000_frame_base_address,
+ rs6000_frame_base_address
+};
+
+static const struct frame_base *
+rs6000_frame_base_sniffer (const struct frame_base_sniffer *self,
+ struct frame_info *next_frame)
+{
+ return &rs6000_frame_base;
+}
/* Initialize the current architecture based on INFO. If possible, re-use an
architecture from ARCHES, which is a list of architectures already created
@@ -3157,8 +3154,9 @@ rs6000_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
case GDB_OSABI_UNKNOWN:
case GDB_OSABI_LINUX:
set_gdbarch_unwind_pc (gdbarch, rs6000_unwind_pc);
- trad_frame_append (gdbarch, &rs6000_trad_frame);
+ frame_unwind_append_sniffer (gdbarch, rs6000_frame_sniffer);
set_gdbarch_unwind_dummy_id (gdbarch, rs6000_unwind_dummy_id);
+ frame_base_append_sniffer (gdbarch, rs6000_frame_base_sniffer);
break;
default:
set_gdbarch_deprecated_save_dummy_frame_tos (gdbarch, generic_save_dummy_frame_tos);
diff --git a/gdb/solib-svr4.c b/gdb/solib-svr4.c
index 920595e9508..c9fdff2b26b 100644
--- a/gdb/solib-svr4.c
+++ b/gdb/solib-svr4.c
@@ -1490,7 +1490,7 @@ void
set_solib_svr4_fetch_link_map_offsets (struct gdbarch *gdbarch,
struct link_map_offsets *(*flmo) (void))
{
- set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo);
+ deprecated_set_gdbarch_data (gdbarch, fetch_link_map_offsets_gdbarch_data, flmo);
}
/* Initialize the architecture-specific link_map_offsets fetcher.
@@ -1588,7 +1588,7 @@ void
_initialize_svr4_solib (void)
{
fetch_link_map_offsets_gdbarch_data =
- register_gdbarch_data (NULL, init_fetch_link_map_offsets);
+ gdbarch_data_register_post_init (init_fetch_link_map_offsets);
svr4_so_ops.relocate_section_addresses = svr4_relocate_section_addresses;
svr4_so_ops.free_so = svr4_free_so;
diff --git a/gdb/solib-svr4.h b/gdb/solib-svr4.h
index d76c7f51459..5dc13c60e4b 100644
--- a/gdb/solib-svr4.h
+++ b/gdb/solib-svr4.h
@@ -20,6 +20,9 @@
Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
+#ifndef SOLIB_SVR4
+#define SOLIB_SVR4
+
struct objfile;
/* Critical offsets and sizes which describe struct r_debug and
@@ -88,3 +91,5 @@ extern struct link_map_offsets *(*legacy_svr4_fetch_link_map_offsets_hook)(void)
for ILP32 and LP64 SVR4 systems. */
extern struct link_map_offsets *svr4_ilp32_fetch_link_map_offsets (void);
extern struct link_map_offsets *svr4_lp64_fetch_link_map_offsets (void);
+
+#endif
diff --git a/gdb/trad-frame.c b/gdb/trad-frame.c
index fe981b16dd3..8cca61937ff 100644
--- a/gdb/trad-frame.c
+++ b/gdb/trad-frame.c
@@ -41,11 +41,11 @@ trad_frame_cache_zalloc (struct frame_info *next_frame)
int regnum;
trad_cache = FRAME_OBSTACK_ZALLOC (struct trad_frame_cache);
- trad_cache->prev_regs = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
+ trad_cache->saved_regs = FRAME_OBSTACK_CALLOC (numregs, struct trad_frame_saved_reg);
for (regnum = 0; regnum < numregs; regnum++)
{
- trad_cache->prev_regs[regnum].realreg = regnum;
- trad_cache->prev_regs[regnum].addr = -1;
+ trad_cache->saved_regs[regnum].realreg = regnum;
+ trad_cache->saved_regs[regnum].addr = -1;
}
return trad_cache;
}
@@ -55,32 +55,42 @@ enum { REG_VALUE = -1, REG_UNKNOWN = -2 };
int
trad_frame_value_p (struct trad_frame_cache *this_cache, int regnum)
{
- return (this_cache->prev_regs[regnum].realreg == REG_VALUE);
+ return (this_cache->saved_regs[regnum].realreg == REG_VALUE);
}
int
trad_frame_addr_p (struct trad_frame_cache *this_cache, int regnum)
{
- return (this_cache->prev_regs[regnum].realreg >= 0
- && this_cache->prev_regs[regnum].addr != -1);
+ return (this_cache->saved_regs[regnum].realreg >= 0
+ && this_cache->saved_regs[regnum].addr != -1);
}
int
trad_frame_realreg_p (struct trad_frame_cache *this_cache,
int regnum)
{
- return (this_cache->prev_regs[regnum].realreg >= 0
- && this_cache->prev_regs[regnum].addr == -1);
+ return (this_cache->saved_regs[regnum].realreg >= 0
+ && this_cache->saved_regs[regnum].addr == -1);
}
void
-trad_frame_set_value (struct trad_frame_cache *this_cache,
- int regnum, LONGEST val)
+trad_frame_set_reg_value (struct trad_frame_cache *this_cache,
+ int regnum, LONGEST val)
{
/* Make the REALREG invalid, indicating that the ADDR contains the
register's value. */
- this_cache->prev_regs[regnum].realreg = REG_VALUE;
- this_cache->prev_regs[regnum].addr = val;
+ this_cache->saved_regs[regnum].realreg = REG_VALUE;
+ this_cache->saved_regs[regnum].addr = val;
+}
+
+void
+trad_frame_set_addr (struct trad_frame_cache *this_cache,
+ int regnum, CORE_ADDR addr)
+{
+ /* Make the REALREG invalid, indicating that the ADDR contains the
+ register's value. */
+ this_cache->saved_regs[regnum].realreg = regnum;
+ this_cache->saved_regs[regnum].addr = addr;
}
void
@@ -88,8 +98,8 @@ trad_frame_set_unknown (struct trad_frame_cache *this_cache,
int regnum)
{
/* Make the REALREG invalid, indicating that the value is not known. */
- this_cache->prev_regs[regnum].realreg = REG_UNKNOWN;
- this_cache->prev_regs[regnum].addr = -1;
+ this_cache->saved_regs[regnum].realreg = REG_UNKNOWN;
+ this_cache->saved_regs[regnum].addr = -1;
}
struct frame_data
@@ -99,50 +109,34 @@ struct frame_data
const struct trad_frame *trad_frame;
};
-static struct trad_frame_cache *
-trad_frame_cache (const struct frame_data *self,
- struct frame_info *next_frame,
- void **this_cache)
-{
- if ((*this_cache) == NULL)
- {
- (*this_cache) = trad_frame_cache_zalloc (next_frame);
- gdb_assert (self->trad_frame->init != NULL);
- self->trad_frame->init (self->trad_frame, next_frame, (*this_cache));
- }
- return (*this_cache);
-}
-
-static void
-trad_frame_prev_register (const struct frame_unwind *self,
+void
+trad_frame_prev_register (struct trad_frame_cache *trad_cache,
struct frame_info *next_frame,
- void **this_cache,
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realregp, void *bufferp)
{
- struct trad_frame_cache *trad_cache
- = trad_frame_cache (self->unwind_data, next_frame, this_cache);
struct gdbarch *gdbarch = get_frame_arch (next_frame);
+ gdb_assert (trad_cache != NULL);
if (trad_frame_addr_p (trad_cache, regnum))
{
/* The register was saved in memory. */
*optimizedp = 0;
*lvalp = lval_memory;
- *addrp = trad_cache->prev_regs[regnum].addr;
+ *addrp = trad_cache->saved_regs[regnum].addr;
*realregp = -1;
if (bufferp != NULL)
{
/* Read the value in from memory. */
- get_frame_memory (next_frame, trad_cache->prev_regs[regnum].addr, bufferp,
+ get_frame_memory (next_frame, trad_cache->saved_regs[regnum].addr, bufferp,
register_size (gdbarch, regnum));
}
}
else if (trad_frame_realreg_p (trad_cache, regnum))
{
/* Ask the next frame to return the value of the register. */
- frame_register_unwind (next_frame, trad_cache->prev_regs[regnum].realreg,
+ frame_register_unwind (next_frame, trad_cache->saved_regs[regnum].realreg,
optimizedp, lvalp, addrp, realregp, bufferp);
}
else if (trad_frame_value_p (trad_cache, regnum))
@@ -154,7 +148,7 @@ trad_frame_prev_register (const struct frame_unwind *self,
*realregp = -1;
if (bufferp != NULL)
store_unsigned_integer (bufferp, register_size (gdbarch, regnum),
- trad_cache->prev_regs[regnum].addr);
+ trad_cache->saved_regs[regnum].addr);
}
else
{
@@ -163,26 +157,22 @@ trad_frame_prev_register (const struct frame_unwind *self,
}
}
-static void
-trad_frame_this_id (const struct frame_unwind *self,
- struct frame_info *next_frame, void **this_cache,
+void
+trad_frame_this_id (struct trad_frame_cache *trad_cache,
+ struct frame_info *next_frame,
struct frame_id *this_id)
{
- struct trad_frame_cache *trad_cache
- = trad_frame_cache (self->unwind_data, next_frame, this_cache);
+ gdb_assert (trad_cache != NULL);
(*this_id) = trad_cache->this_id;
}
-static const struct frame_unwind *
-trad_frame_unwind_sniffer (const struct frame_unwind_sniffer *self,
- struct frame_info *next_frame)
+static void *
+trad_frame_sniffer (const struct frame_unwind *self,
+ struct frame_info *next_frame)
{
- const struct trad_frame *trad_frame = self->sniffer_data->trad_frame;
+ const struct trad_frame *trad_frame = self->unwind_data->trad_frame;
gdb_assert (trad_frame->sniffer != NULL);
- if (trad_frame->sniffer (trad_frame, next_frame))
- return self->sniffer_data->frame_unwind;
- else
- return NULL;
+ return trad_frame->sniffer (trad_frame, next_frame);
}
static CORE_ADDR
@@ -190,8 +180,9 @@ trad_frame_base (const struct frame_base *self,
struct frame_info *next_frame,
void **this_cache)
{
- struct trad_frame_cache *trad_cache
- = trad_frame_cache (self->base_data, next_frame, this_cache);
+ struct trad_frame_cache *trad_cache = (*this_cache);
+
+ gdb_assert (trad_cache != NULL);
return trad_cache->this_base;
}
@@ -207,19 +198,19 @@ trad_frame_base_sniffer (const struct frame_base_sniffer *self,
return NULL;
}
+#if 0
void
trad_frame_append (struct gdbarch *gdbarch,
const struct trad_frame *trad_frame)
{
struct frame_data *data;
struct frame_unwind *unwind;
- struct frame_unwind_sniffer *unwind_sniffer;
struct frame_base *base;
struct frame_base_sniffer *base_sniffer;
data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
unwind = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
- unwind_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind_sniffer);
+
base = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_base);
base_sniffer = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_base_sniffer);
@@ -231,10 +222,9 @@ trad_frame_append (struct gdbarch *gdbarch,
unwind->this_id = trad_frame_this_id;
unwind->prev_register = trad_frame_prev_register;
unwind->unwind_data = data;
- unwind_sniffer->sniffer = trad_frame_unwind_sniffer;
- unwind_sniffer->sniffer_data = data;
+ unwind->sniffer = trad_frame_sniffer;
- frame_unwind_sniffer_append (gdbarch, unwind_sniffer);
+ frame_unwind_append (gdbarch, unwind);
base->base_data = data;
base->unwind = unwind;
@@ -247,3 +237,4 @@ trad_frame_append (struct gdbarch *gdbarch,
frame_base_sniffer_append (gdbarch, base_sniffer);
}
+#endif
diff --git a/gdb/trad-frame.h b/gdb/trad-frame.h
index ae2722eefb7..6af0df301ac 100644
--- a/gdb/trad-frame.h
+++ b/gdb/trad-frame.h
@@ -63,51 +63,66 @@ struct trad_frame_cache
{
struct frame_id this_id;
CORE_ADDR this_base;
- struct trad_frame_saved_reg *prev_regs;
+ struct trad_frame_saved_reg *saved_regs;
};
+struct trad_frame_cache *trad_frame_cache_zalloc (struct frame_info *next_frame);
+
+
/* Encode REGNUM's value in the trad-frame. */
-void trad_frame_set_value (struct trad_frame_cache *this_cache,
- int regnum, LONGEST val);
-void trad_frame_set_addr (struct trad_frame_cache *this_cache,
- int regnum, CORE_ADDR addr);
-void trad_frame_set_realreg (struct trad_frame_cache *this_cache,
- int regnum, int realreg);
-void trad_frame_set_unknown (struct trad_frame_cache *this_cache,
- int regnum);
+void trad_frame_set_reg_value (struct trad_frame_cache *this_cache,
+ int regnum, LONGEST val);
+void trad_frame_set_reg_addr (struct trad_frame_cache *this_cache,
+ int regnum, CORE_ADDR addr);
+void trad_frame_set_reg_reg (struct trad_frame_cache *this_cache,
+ int regnum, int realreg);
+void trad_frame_set_reg_unknown (struct trad_frame_cache *this_cache,
+ int regnum);
+void trad_frame_set_this_id (struct trad_frame_cache *this_cache,
+ struct frame_id *this_id);
+void trad_frame_set_this_base (struct trad_frame_cache *this_cache,
+ CORE_ADDR base);
/* Set the offset of a register, and then update all offsets. Useful
when the offset of a register is known before its absolute
address. */
-void trad_frame_set_offset (struct trad_frame_cache *this_cache,
- int regnum, LONGEST addr);
-void trad_frame_add_addr (struct trad_frame_cache *this_cache,
- int regnum, CORE_ADDR addr);
+void trad_frame_set_reg_offset (struct trad_frame_cache *this_cache,
+ int regnum, LONGEST addr);
+void trad_frame_add_reg_addr (struct trad_frame_cache *this_cache,
+ int regnum, CORE_ADDR addr);
/* Convenience functions, return non-zero if the register has been
encoded as specified. */
-int trad_frame_value_p (struct trad_frame_cache *this_cache,
- int regnum);
-int trad_frame_addr_p (struct trad_frame_cache *this_cache,
- int regnum);
-int trad_frame_realreg_p (struct trad_frame_cache *this_cache,
+int trad_frame_reg_value_p (struct trad_frame_cache *this_cache,
+ int regnum);
+int trad_frame_reg_addr_p (struct trad_frame_cache *this_cache,
+ int regnum);
+int trad_frame_reg_reg_p (struct trad_frame_cache *this_cache,
int regnum);
-typedef void (trad_frame_init_ftype) (const struct trad_frame *self,
- struct frame_info *next_frame,
- struct trad_frame_cache *this_cache);
-typedef int (trad_frame_sniffer_ftype) (const struct trad_frame *self,
- struct frame_info *next_frame);
+typedef struct trad_frame_cache *(trad_frame_sniffer_ftype) (const struct trad_frame *self,
+ struct frame_info *next_frame);
struct trad_frame
{
enum frame_type type;
trad_frame_sniffer_ftype *sniffer;
- trad_frame_init_ftype *init;
const struct trad_frame_data *trad_data;
};
void trad_frame_append (struct gdbarch *gdbarch,
const struct trad_frame *trad_frame);
+void trad_frame_this_id (struct trad_frame_cache *trad_cache,
+ struct frame_info *next_frame,
+ struct frame_id *this_id);
+
+void trad_frame_prev_register (struct trad_frame_cache *trad_cache,
+ struct frame_info *next_frame,
+ int prev_regnum,
+ int *optimizedp,
+ enum lval_type * lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep);
+
#endif
diff --git a/gdb/tramp-frame.c b/gdb/tramp-frame.c
index 376ab364653..096beb65509 100644
--- a/gdb/tramp-frame.c
+++ b/gdb/tramp-frame.c
@@ -21,18 +21,69 @@
#include "defs.h"
#include "tramp-frame.h"
-#include "trad-frame.h"
#include "frame-unwind.h"
#include "gdbcore.h"
#include "symtab.h"
#include "objfiles.h"
#include "target.h"
+#include "trad-frame.h"
-struct trad_frame_data
+struct frame_data
{
const struct tramp_frame *tramp_frame;
};
+struct tramp_frame_cache
+{
+ CORE_ADDR func;
+ struct trad_frame_cache *trad_cache;
+};
+
+static struct trad_frame_cache *
+tramp_frame_cache (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_cache)
+{
+ CORE_ADDR pc = frame_pc_unwind (next_frame);
+ struct tramp_frame_cache *tramp_cache = (*this_cache);
+ if (tramp_cache->trad_cache == NULL)
+ {
+ tramp_cache->trad_cache = trad_frame_cache_zalloc (next_frame);
+ self->unwind_data->tramp_frame->init (self->unwind_data->tramp_frame,
+ next_frame,
+ tramp_cache->trad_cache,
+ tramp_cache->func);
+ }
+ return tramp_cache->trad_cache;
+}
+
+static void
+tramp_frame_this_id (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_cache,
+ struct frame_id *this_id)
+{
+ struct trad_frame_cache *trad_cache
+ = tramp_frame_cache (self, next_frame, this_cache);
+ trad_frame_this_id (trad_cache, next_frame, this_id);
+}
+
+static void
+tramp_frame_prev_register (const struct frame_unwind *self,
+ struct frame_info *next_frame,
+ void **this_cache,
+ int prev_regnum,
+ int *optimizedp,
+ enum lval_type * lvalp,
+ CORE_ADDR *addrp,
+ int *realnump, void *valuep)
+{
+ struct trad_frame_cache *trad_cache
+ = tramp_frame_cache (self, next_frame, this_cache);
+ trad_frame_prev_register (trad_cache, next_frame, prev_regnum, optimizedp,
+ lvalp, addrp, realnump, valuep);
+}
+
static CORE_ADDR
tramp_frame_start (CORE_ADDR pc, const struct tramp_frame *tramp)
{
@@ -61,23 +112,16 @@ tramp_frame_start (CORE_ADDR pc, const struct tramp_frame *tramp)
return 0;
}
-static void
-tramp_frame_init (const struct trad_frame *self,
- struct frame_info *next_frame,
- struct trad_frame_cache *this_cache)
-{
- CORE_ADDR pc = frame_pc_unwind (next_frame);
- const struct tramp_frame *tramp = self->trad_data->tramp_frame;
- tramp->init (tramp, next_frame, this_cache, tramp_frame_start (pc, tramp));
-}
-
-static int
-tramp_frame_sniffer (const struct trad_frame *self,
+static void *
+tramp_frame_sniffer (const struct frame_unwind *self,
struct frame_info *next_frame)
{
- const struct tramp_frame *tramp = self->trad_data->tramp_frame;
+ const struct tramp_frame *tramp = self->unwind_data->tramp_frame;
CORE_ADDR pc = frame_pc_unwind (next_frame);
+ CORE_ADDR func;
char *name;
+ struct tramp_frame_cache *tramp_cache;
+
/* If the function has a valid symbol name, it isn't a
trampoline. */
find_pc_partial_function (pc, &name, NULL, NULL);
@@ -87,25 +131,31 @@ tramp_frame_sniffer (const struct trad_frame *self,
point) it isn't a trampoline. */
if (find_pc_section (pc) != NULL)
return NULL;
- /* The problem here is that this code, and tramp_frame_cache, both
- end up doing a search to find the function start :-(. */
- return (tramp_frame_start (pc, tramp) != 0);
+ /* Finally, check that the trampoline matches at PC. */
+ func = tramp_frame_start (pc, tramp);
+ if (func == 0)
+ return NULL;
+ tramp_cache = FRAME_OBSTACK_ZALLOC (struct tramp_frame_cache);
+ tramp_cache->func = func;
+ return tramp_cache;
}
void
tramp_frame_append (struct gdbarch *gdbarch,
- const struct tramp_frame *tramp)
+ const struct tramp_frame *tramp_frame)
{
- struct trad_frame_data *trad_data;
- struct trad_frame *trad;
-
- trad_data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct trad_frame_data);
- trad = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct trad_frame);
-
- trad_data->tramp_frame = tramp;
- trad->type = SIGTRAMP_FRAME;
- trad->trad_data = trad_data;
- trad->sniffer = tramp_frame_sniffer;
- trad->init = tramp_frame_init;
- trad_frame_append (gdbarch, trad);
+ struct frame_data *data;
+ struct frame_unwind *unwinder;
+
+ data = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_data);
+ unwinder = GDBARCH_OBSTACK_ZALLOC (gdbarch, struct frame_unwind);
+
+ data->tramp_frame = tramp_frame;
+ unwinder->type = SIGTRAMP_FRAME;
+ unwinder->unwind_data = data;
+ unwinder->sniffer = tramp_frame_sniffer;
+ unwinder->this_id = tramp_frame_this_id;
+ unwinder->prev_register = tramp_frame_prev_register;
+
+ frame_unwind_append (gdbarch, unwinder);
}
diff --git a/gdb/user-regs.c b/gdb/user-regs.c
index f65f59e0ca8..b611d601919 100644
--- a/gdb/user-regs.c
+++ b/gdb/user-regs.c
@@ -110,7 +110,7 @@ user_reg_add (struct gdbarch *gdbarch, const char *name,
/* ULGH, called during architecture initialization. Patch
things up. */
regs = user_regs_init (gdbarch);
- set_gdbarch_data (gdbarch, user_regs_data, regs);
+ deprecated_set_gdbarch_data (gdbarch, user_regs_data, regs);
}
append_user_reg (regs, name, read,
GDBARCH_OBSTACK_ZALLOC (gdbarch, struct user_reg));
@@ -207,5 +207,5 @@ extern initialize_file_ftype _initialize_user_regs; /* -Wmissing-prototypes */
void
_initialize_user_regs (void)
{
- user_regs_data = register_gdbarch_data (NULL, user_regs_init);
+ user_regs_data = gdbarch_data_register_post_init (user_regs_init);
}