aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2/frame.c
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2/frame.c')
-rw-r--r--gdb/dwarf2/frame.c60
1 files changed, 60 insertions, 0 deletions
diff --git a/gdb/dwarf2/frame.c b/gdb/dwarf2/frame.c
index bd36a6c..7f2bcf2 100644
--- a/gdb/dwarf2/frame.c
+++ b/gdb/dwarf2/frame.c
@@ -831,6 +831,22 @@ dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
}
+/* Custom function data object for architecture specific prev_register
+ implementation. Main purpose of this object is to allow caching of
+ expensive data lookups in the prev_register handling. */
+
+struct dwarf2_frame_fn_data
+{
+ /* The cookie to identify the custom function data by. */
+ fn_prev_register cookie;
+
+ /* The custom function data. */
+ void *data;
+
+ /* Pointer to the next custom function data object for this frame. */
+ struct dwarf2_frame_fn_data *next;
+};
+
struct dwarf2_frame_cache
{
/* DWARF Call Frame Address. */
@@ -862,6 +878,8 @@ struct dwarf2_frame_cache
dwarf2_tailcall_frame_unwind unwinder so this field does not apply for
them. */
void *tailcall_cache;
+
+ struct dwarf2_frame_fn_data *fn_data;
};
static struct dwarf2_frame_cache *
@@ -1221,6 +1239,48 @@ dwarf2_frame_prev_register (frame_info_ptr this_frame, void **this_cache,
}
}
+/* See frame.h. */
+
+void *
+dwarf2_frame_get_fn_data (frame_info_ptr this_frame, void **this_cache,
+ fn_prev_register cookie)
+{
+ struct dwarf2_frame_fn_data *fn_data = nullptr;
+ struct dwarf2_frame_cache *cache
+ = dwarf2_frame_cache (this_frame, this_cache);
+
+ /* Find the object for the function. */
+ for (fn_data = cache->fn_data; fn_data; fn_data = fn_data->next)
+ if (fn_data->cookie == cookie)
+ return fn_data->data;
+
+ return nullptr;
+}
+
+/* See frame.h. */
+
+void *
+dwarf2_frame_allocate_fn_data (frame_info_ptr this_frame, void **this_cache,
+ fn_prev_register cookie, unsigned long size)
+{
+ struct dwarf2_frame_fn_data *fn_data = nullptr;
+ struct dwarf2_frame_cache *cache
+ = dwarf2_frame_cache (this_frame, this_cache);
+
+ /* First try to find an existing object. */
+ void *data = dwarf2_frame_get_fn_data (this_frame, this_cache, cookie);
+ gdb_assert (data == nullptr);
+
+ /* No object found, lets create a new instance. */
+ fn_data = FRAME_OBSTACK_ZALLOC (struct dwarf2_frame_fn_data);
+ fn_data->cookie = cookie;
+ fn_data->data = frame_obstack_zalloc (size);
+ fn_data->next = cache->fn_data;
+ cache->fn_data = fn_data;
+
+ return fn_data->data;
+}
+
/* Proxy for tailcall_frame_dealloc_cache for bottom frame of a virtual tail
call frames chain. */