summaryrefslogtreecommitdiff
path: root/gdb/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/frame.c')
-rw-r--r--gdb/frame.c107
1 files changed, 70 insertions, 37 deletions
diff --git a/gdb/frame.c b/gdb/frame.c
index 3b17bf5abf0..1ad3b09f3bd 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -27,6 +27,8 @@
#include "inferior.h" /* for inferior_ptid */
#include "regcache.h"
#include "gdb_assert.h"
+#include "gdb_string.h"
+#include "builtin-regs.h"
/* Return a frame uniq ID that can be used to, later re-find the
frame. */
@@ -78,43 +80,6 @@ frame_find_by_id (struct frame_id id)
return NULL;
}
-/* FIND_SAVED_REGISTER ()
-
- Return the address in which frame FRAME's value of register REGNUM
- has been saved in memory. Or return zero if it has not been saved.
- If REGNUM specifies the SP, the value we return is actually
- the SP value, not an address where it was saved. */
-
-CORE_ADDR
-find_saved_register (struct frame_info *frame, int regnum)
-{
- register struct frame_info *frame1 = NULL;
- register CORE_ADDR addr = 0;
-
- if (frame == NULL) /* No regs saved if want current frame */
- return 0;
-
- /* Note that the following loop assumes that registers used in
- frame x will be saved only in the frame that x calls and frames
- interior to it. */
- while (1)
- {
- QUIT;
- frame1 = get_next_frame (frame);
- if (frame1 == 0)
- break;
- frame = frame1;
- FRAME_INIT_SAVED_REGS (frame1);
- if (frame1->saved_regs[regnum])
- {
- addr = frame1->saved_regs[regnum];
- break;
- }
- }
-
- return addr;
-}
-
void
frame_register_unwind (struct frame_info *frame, int regnum,
int *optimizedp, enum lval_type *lvalp,
@@ -159,6 +124,33 @@ frame_register_unwind (struct frame_info *frame, int regnum,
optimizedp, lvalp, addrp, realnump, bufferp);
}
+void
+frame_unwind_signed_register (struct frame_info *frame, int regnum,
+ LONGEST *val)
+{
+ int optimized;
+ CORE_ADDR addr;
+ int realnum;
+ enum lval_type lval;
+ void *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ frame_register_unwind (frame, regnum, &optimized, &lval, &addr,
+ &realnum, buf);
+ (*val) = extract_signed_integer (buf, REGISTER_VIRTUAL_SIZE (regnum));
+}
+
+void
+frame_unwind_unsigned_register (struct frame_info *frame, int regnum,
+ ULONGEST *val)
+{
+ int optimized;
+ CORE_ADDR addr;
+ int realnum;
+ enum lval_type lval;
+ void *buf = alloca (MAX_REGISTER_RAW_SIZE);
+ frame_register_unwind (frame, regnum, &optimized, &lval, &addr,
+ &realnum, buf);
+ (*val) = extract_unsigned_integer (buf, REGISTER_VIRTUAL_SIZE (regnum));
+}
void
generic_unwind_get_saved_register (char *raw_buffer,
@@ -243,3 +235,44 @@ frame_register_read (struct frame_info *frame, int regnum, void *myaddr)
return !optim;
}
+
+
+/* Map between a frame register number and its name. A frame register
+ space is a superset of the cooked register space --- it also
+ includes builtin registers. */
+
+int
+frame_map_name_to_regnum (const char *name, int len)
+{
+ int i;
+
+ /* Search register name space. */
+ for (i = 0; i < NUM_REGS + NUM_PSEUDO_REGS; i++)
+ if (REGISTER_NAME (i) && len == strlen (REGISTER_NAME (i))
+ && strncmp (name, REGISTER_NAME (i), len) == 0)
+ {
+ return i;
+ }
+
+ /* Try builtin registers. */
+ i = builtin_reg_map_name_to_regnum (name, len);
+ if (i >= 0)
+ {
+ /* A builtin register doesn't fall into the architecture's
+ register range. */
+ gdb_assert (i >= NUM_REGS + NUM_PSEUDO_REGS);
+ return i;
+ }
+
+ return -1;
+}
+
+const char *
+frame_map_regnum_to_name (int regnum)
+{
+ if (regnum < 0)
+ return NULL;
+ if (regnum < NUM_REGS + NUM_PSEUDO_REGS)
+ return REGISTER_NAME (regnum);
+ return builtin_reg_map_regnum_to_name (regnum);
+}