- /* Use an architecture specific method to extract the prev's dummy
- ID from the next frame. Note that this method uses
- frame_register_unwind to obtain the register values needed to
- determine the dummy frame's ID. */
- gdb_assert (gdbarch_unwind_dummy_id_p (current_gdbarch));
- (*this_id) = gdbarch_unwind_dummy_id (current_gdbarch, next_frame);
- (*this_prologue_cache) = find_dummy_frame ((*this_id).code_addr,
- (*this_id).stack_addr);
+
+ /* Don't bother unless there is at least one dummy frame. */
+ if (dummy_frame_stack != NULL)
+ {
+ struct dummy_frame *dummyframe;
+ /* Use an architecture specific method to extract this frame's
+ dummy ID, assuming it is a dummy frame. */
+ struct frame_id this_id
+ = gdbarch_dummy_id (get_frame_arch (this_frame), this_frame);
+ struct dummy_frame_id dummy_id = { this_id, inferior_thread () };
+
+ /* Use that ID to find the corresponding cache entry. */
+ for (dummyframe = dummy_frame_stack;
+ dummyframe != NULL;
+ dummyframe = dummyframe->next)
+ {
+ if (dummy_frame_id_eq (&dummyframe->id, &dummy_id))
+ {
+ struct dummy_frame_cache *cache;
+
+ cache = FRAME_OBSTACK_ZALLOC (struct dummy_frame_cache);
+ cache->prev_regcache = get_infcall_suspend_state_regcache
+ (dummyframe->caller_state);
+ cache->this_id = this_id;
+ (*this_prologue_cache) = cache;
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+/* Given a call-dummy dummy-frame, return the registers. Here the
+ register value is taken from the local copy of the register buffer. */
+
+static struct value *
+dummy_frame_prev_register (struct frame_info *this_frame,
+ void **this_prologue_cache,
+ int regnum)
+{
+ struct dummy_frame_cache *cache
+ = (struct dummy_frame_cache *) *this_prologue_cache;
+ struct gdbarch *gdbarch = get_frame_arch (this_frame);
+ struct value *reg_val;
+
+ /* The dummy-frame sniffer always fills in the cache. */
+ gdb_assert (cache != NULL);
+
+ /* Describe the register's location. Generic dummy frames always
+ have the register value in an ``expression''. */
+ reg_val = value_zero (register_type (gdbarch, regnum), not_lval);
+
+ /* Use the regcache_cooked_read() method so that it, on the fly,
+ constructs either a raw or pseudo register from the raw
+ register cache. */
+ cache->prev_regcache->cooked_read (regnum,
+ value_contents_writeable (reg_val));
+ return reg_val;
+}
+
+/* Assuming that THIS_FRAME is a dummy, return its ID. That ID is
+ determined by examining the NEXT frame's unwound registers using
+ the method dummy_id(). As a side effect, THIS dummy frame's
+ dummy cache is located and saved in THIS_PROLOGUE_CACHE. */
+
+static void
+dummy_frame_this_id (struct frame_info *this_frame,
+ void **this_prologue_cache,
+ struct frame_id *this_id)
+{
+ /* The dummy-frame sniffer always fills in the cache. */
+ struct dummy_frame_cache *cache
+ = (struct dummy_frame_cache *) *this_prologue_cache;
+
+ gdb_assert (cache != NULL);
+ (*this_id) = cache->this_id;