aboutsummaryrefslogtreecommitdiff
path: root/gdb/dwarf2
diff options
context:
space:
mode:
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r--gdb/dwarf2/frame.c60
-rw-r--r--gdb/dwarf2/frame.h37
2 files changed, 95 insertions, 2 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. */
diff --git a/gdb/dwarf2/frame.h b/gdb/dwarf2/frame.h
index 4444c15..5643e55 100644
--- a/gdb/dwarf2/frame.h
+++ b/gdb/dwarf2/frame.h
@@ -66,6 +66,9 @@ enum dwarf2_frame_reg_rule
/* Register state. */
+typedef struct value *(*fn_prev_register) (frame_info_ptr this_frame,
+ void **this_cache, int regnum);
+
struct dwarf2_frame_state_reg
{
/* Each register save state can be described in terms of a CFA slot,
@@ -78,8 +81,7 @@ struct dwarf2_frame_state_reg
const gdb_byte *start;
ULONGEST len;
} exp;
- struct value *(*fn) (frame_info_ptr this_frame, void **this_cache,
- int regnum);
+ fn_prev_register fn;
} loc;
enum dwarf2_frame_reg_rule how;
};
@@ -262,4 +264,35 @@ extern int dwarf2_fetch_cfa_info (struct gdbarch *gdbarch, CORE_ADDR pc,
const gdb_byte **cfa_start_out,
const gdb_byte **cfa_end_out);
+
+/* Allocate a new instance of the function unique data.
+
+ The main purpose of this custom function data object is to allow caching the
+ value of expensive lookups in the prev_register implementation.
+
+ THIS_FRAME is the frame that the custom data object should be associated
+ with.
+ THIS_CACHE is the dwarf2 cache object to store the pointer on.
+ COOKIE is the key for the prev_function implementation.
+ SIZE is the size of the custom data object to allocate. */
+
+extern void *dwarf2_frame_allocate_fn_data (frame_info_ptr this_frame,
+ void **this_cache,
+ fn_prev_register cookie,
+ unsigned long size);
+
+/* Retrieve the function unique data for this frame or NULL if none exists.
+
+ The main purpose of this custom function data object is to allow caching the
+ value of expensive lookups in the prev_register implementation.
+
+ THIS_FRAME is the frame that the custom data object should be associated
+ with.
+ THIS_CACHE is the dwarf2 cache object to store the pointer on.
+ COOKIE is the key for the prev_function implementation. */
+
+extern void *dwarf2_frame_get_fn_data (frame_info_ptr this_frame,
+ void **this_cache,
+ fn_prev_register cookie);
+
#endif /* dwarf2-frame.h */