#define tdep_init UNW_OBJ(init)
#define arm_find_proc_info UNW_OBJ(find_proc_info)
#define arm_put_unwind_info UNW_OBJ(put_unwind_info)
+#define arm_cb_cache_data_init UNW_OBJ(cb_cache_data_init)
+
/* Platforms that support UNW_INFO_FORMAT_TABLE need to define
tdep_search_unwind_table. */
#define tdep_search_unwind_table UNW_OBJ(search_unwind_table)
void *arg);
extern void arm_put_unwind_info (unw_addr_space_t as,
unw_proc_info_t *pi, void *arg);
+extern void arm_cb_cache_data_init (void);
extern int tdep_search_unwind_table (unw_addr_space_t as, unw_word_t ip,
unw_dyn_info_t *di, unw_proc_info_t *pi,
int need_unwind_info, void *arg);
/**
* Callback to dl_iterate_phdr to find infos about the ARM exidx segment.
*/
+struct arm_cb_cache_data
+{
+ unw_word_t start_ip;
+ unw_word_t end_ip;
+ unw_word_t name_ptr;
+ unw_word_t table_data;
+ unw_word_t table_len;
+};
+static struct arm_cb_cache_data g_cache_data = {0, 0, 0, 0, 0};
+
static int
arm_phdr_cb (struct dl_phdr_info *info, size_t size, void *data)
{
cb_data.di.format = -1;
SIGPROCMASK (SIG_SETMASK, &unwi_full_mask, &saved_mask);
- ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ if (ip >= g_cache_data.start_ip && ip < g_cache_data.end_ip)
+ {
+ cb_data.di.format = UNW_INFO_FORMAT_ARM_EXIDX;
+ cb_data.di.start_ip = g_cache_data.start_ip;
+ cb_data.di.end_ip = g_cache_data.end_ip;
+ cb_data.di.u.rti.name_ptr = g_cache_data.name_ptr;
+ cb_data.di.u.rti.table_data = g_cache_data.table_data;
+ cb_data.di.u.rti.table_len = g_cache_data.table_len;
+ }
+ else
+ {
+ ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ }
+
SIGPROCMASK (SIG_SETMASK, &saved_mask, NULL);
if (cb_data.di.format != -1)
{
/* it's a no-op */
}
+
+HIDDEN void
+arm_cb_cache_data_init(void)
+{
+ struct arm_cb_data cb_data;
+ memset (&cb_data, 0, sizeof (cb_data));
+ cb_data.ip = (unw_word_t)arm_cb_cache_data_init;
+ cb_data.pi = 0;
+ cb_data.di.format = -1;
+
+ int ret = dl_iterate_phdr (arm_phdr_cb, &cb_data);
+ if (ret > 0)
+ {
+ g_cache_data.start_ip = cb_data.di.start_ip;
+ g_cache_data.end_ip = cb_data.di.end_ip;
+ g_cache_data.name_ptr = cb_data.di.u.rti.name_ptr;
+ g_cache_data.table_data = cb_data.di.u.rti.table_data;
+ g_cache_data.table_len = cb_data.di.u.rti.table_len;
+ }
+}
#endif /* !UNW_REMOTE_ONLY */