aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndreas Schwab <schwab@linux-m68k.org>2007-06-12 15:21:27 +0000
committerAndreas Schwab <schwab@linux-m68k.org>2007-06-12 15:21:27 +0000
commit272dfcfd78cd900157ff2e4c8c8ed95645dae4f6 (patch)
tree13d19819273e00972d49fd4e14f1bf10157b82b2
parent4339e69e64f47a31e706ba9c1e7c00945c1620ff (diff)
downloadbinutils-272dfcfd78cd900157ff2e4c8c8ed95645dae4f6.zip
binutils-272dfcfd78cd900157ff2e4c8c8ed95645dae4f6.tar.gz
binutils-272dfcfd78cd900157ff2e4c8c8ed95645dae4f6.tar.bz2
* frame-unwind.h (frame_dealloc_cache_ftype): Define.
(struct frame_unwind): Add dealloc_cache. * frame.c (reinit_frame_cache): Call dealloc_cache on all caches. * libunwind-frame.h (libunwind_frame_dealloc_cache): Declare. * libunwind-frame.c (libunwind_frame_dealloc_cache): Define. (libunwind_frame_unwind): Set dealloc_cache. * ia64-tdep.c (ia64_libunwind_frame_unwind): Set dealloc_cache.
-rw-r--r--gdb/ChangeLog11
-rw-r--r--gdb/frame-unwind.h5
-rw-r--r--gdb/frame.c11
-rw-r--r--gdb/ia64-tdep.c6
-rw-r--r--gdb/libunwind-frame.c16
-rw-r--r--gdb/libunwind-frame.h1
6 files changed, 48 insertions, 2 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index d35b3ab..cd4322b 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,14 @@
+2007-06-12 Andreas Schwab <schwab@suse.de>
+
+ * frame-unwind.h (frame_dealloc_cache_ftype): Define.
+ (struct frame_unwind): Add dealloc_cache.
+ * frame.c (reinit_frame_cache): Call dealloc_cache on all caches.
+
+ * libunwind-frame.h (libunwind_frame_dealloc_cache): Declare.
+ * libunwind-frame.c (libunwind_frame_dealloc_cache): Define.
+ (libunwind_frame_unwind): Set dealloc_cache.
+ * ia64-tdep.c (ia64_libunwind_frame_unwind): Set dealloc_cache.
+
2007-06-12 Ulrich Weigand <uweigand@de.ibm.com>
Markus Deuling <deuling@de.ibm.com>
diff --git a/gdb/frame-unwind.h b/gdb/frame-unwind.h
index e1ac871..87c8161 100644
--- a/gdb/frame-unwind.h
+++ b/gdb/frame-unwind.h
@@ -125,6 +125,10 @@ typedef void (frame_prev_register_ftype) (struct frame_info *next_frame,
typedef CORE_ADDR (frame_prev_pc_ftype) (struct frame_info *next_frame,
void **this_prologue_cache);
+/* Deallocate extra memory associated with the frame cache if any. */
+
+typedef void (frame_dealloc_cache_ftype) (struct frame_info *self,
+ void *this_cache);
struct frame_unwind
{
@@ -138,6 +142,7 @@ struct frame_unwind
const struct frame_data *unwind_data;
frame_sniffer_ftype *sniffer;
frame_prev_pc_ftype *prev_pc;
+ frame_dealloc_cache_ftype *dealloc_cache;
};
/* Register a frame unwinder, _prepending_ it to the front of the
diff --git a/gdb/frame.c b/gdb/frame.c
index 6365462..42a44d4 100644
--- a/gdb/frame.c
+++ b/gdb/frame.c
@@ -1077,6 +1077,17 @@ frame_observer_target_changed (struct target_ops *target)
void
reinit_frame_cache (void)
{
+ struct frame_info *fi;
+
+ /* Tear down all frame caches. */
+ for (fi = current_frame; fi != NULL; fi = fi->prev)
+ {
+ if (fi->prologue_cache && fi->unwind->dealloc_cache)
+ fi->unwind->dealloc_cache (fi, fi->prologue_cache);
+ if (fi->base_cache && fi->base->unwind->dealloc_cache)
+ fi->base->unwind->dealloc_cache (fi, fi->base_cache);
+ }
+
/* Since we can't really be sure what the first object allocated was */
obstack_free (&frame_cache_obstack, 0);
obstack_init (&frame_cache_obstack);
diff --git a/gdb/ia64-tdep.c b/gdb/ia64-tdep.c
index 526926c..a462f64 100644
--- a/gdb/ia64-tdep.c
+++ b/gdb/ia64-tdep.c
@@ -2778,7 +2778,11 @@ static const struct frame_unwind ia64_libunwind_frame_unwind =
{
NORMAL_FRAME,
ia64_libunwind_frame_this_id,
- ia64_libunwind_frame_prev_register
+ ia64_libunwind_frame_prev_register,
+ NULL,
+ NULL,
+ NULL,
+ libunwind_frame_dealloc_cache
};
static const struct frame_unwind *
diff --git a/gdb/libunwind-frame.c b/gdb/libunwind-frame.c
index b22e6d7..ebf7eb2 100644
--- a/gdb/libunwind-frame.c
+++ b/gdb/libunwind-frame.c
@@ -65,6 +65,7 @@ struct libunwind_frame_cache
CORE_ADDR base;
CORE_ADDR func_addr;
unw_cursor_t cursor;
+ unw_addr_space_t as;
};
/* We need to qualify the function names with a platform-specific prefix to match
@@ -187,11 +188,20 @@ libunwind_frame_cache (struct frame_info *next_frame, void **this_cache)
}
cache->base = (CORE_ADDR)fp;
+ cache->as = as;
*this_cache = cache;
return cache;
}
+void
+libunwind_frame_dealloc_cache (struct frame_info *self, void *this_cache)
+{
+ struct libunwind_frame_cache *cache = this_cache;
+ if (cache->as)
+ unw_destroy_addr_space_p (cache->as);
+}
+
unw_word_t
libunwind_find_dyn_list (unw_addr_space_t as, unw_dyn_info_t *di, void *arg)
{
@@ -202,7 +212,11 @@ static const struct frame_unwind libunwind_frame_unwind =
{
NORMAL_FRAME,
libunwind_frame_this_id,
- libunwind_frame_prev_register
+ libunwind_frame_prev_register,
+ NULL,
+ NULL,
+ NULL,
+ libunwind_frame_dealloc_cache
};
/* Verify if there is sufficient libunwind information for the frame to use
diff --git a/gdb/libunwind-frame.h b/gdb/libunwind-frame.h
index 499055a..03a1395 100644
--- a/gdb/libunwind-frame.h
+++ b/gdb/libunwind-frame.h
@@ -53,6 +53,7 @@ void libunwind_frame_prev_register (struct frame_info *next_frame, void **this_c
int regnum, int *optimizedp,
enum lval_type *lvalp, CORE_ADDR *addrp,
int *realnump, gdb_byte *valuep);
+void libunwind_frame_dealloc_cache (struct frame_info *self, void *cache);
CORE_ADDR libunwind_frame_base_address (struct frame_info *next_frame, void **this_cache);
int libunwind_is_initialized (void);