diff options
Diffstat (limited to 'gdb/dwarf2')
-rw-r--r-- | gdb/dwarf2/frame.c | 60 | ||||
-rw-r--r-- | gdb/dwarf2/frame.h | 37 |
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 */ |