aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gdb/ChangeLog28
-rw-r--r--gdb/Makefile.in6
-rw-r--r--gdb/defs.h5
-rw-r--r--gdb/doc/ChangeLog5
-rw-r--r--gdb/doc/gdb.texinfo10
-rw-r--r--gdb/dwarf2read.c28
-rw-r--r--gdb/gdbtypes.c145
-rw-r--r--gdb/gdbtypes.h14
-rw-r--r--gdb/objfiles.c4
-rw-r--r--gdb/symfile.c6
-rw-r--r--gdb/tracepoint.c5
-rw-r--r--gdb/utils.c24
-rw-r--r--gdb/value.c72
-rw-r--r--gdb/value.h4
14 files changed, 275 insertions, 81 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog
index ec2c9d7..6ac5565 100644
--- a/gdb/ChangeLog
+++ b/gdb/ChangeLog
@@ -1,3 +1,31 @@
+2006-02-01 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * Makefile.in (gdbtypes_h, gdbtypes.o, utils.o): Update.
+ * defs.h (hashtab_obstack_allocate, dummy_obstack_deallocate): Add
+ prototypes.
+ * dwarf2read.c (read_subroutine_type): Use TYPE_ZALLOC.
+ (hashtab_obstack_allocate, dummy_obstack_deallocate): Moved to...
+ * utils.c (hashtab_obstack_allocate, dummy_obstack_deallocate):
+ ...here.
+ * gdbtypes.c: Include "hashtab.h".
+ (build_gdbtypes): Remove extra prototype.
+ (struct type_pair, type_pair_hash, type_pair_eq)
+ (create_copied_types_hash, copy_type_recursive): New.
+ * gdbtypes.h: Include "hashtab.h".
+ (TYPE_ZALLOC): New.
+ (create_copied_types_hash, copy_type_recursive): New prototypes.
+ * objfiles.c (free_objfile): Call preserve_values.
+ * symfile.c (reread_symbols): Likewise.
+ (clear_symtab_users): Remove calls to clear_value_history and
+ clear_internalvars.
+ * value.c (clear_value_history, clear_internalvars): Removed.
+ (preserve_one_value, preserve_values): New functions.
+ * value.h (clear_value_history, clear_internalvars): Removed.
+ (preserve_values): New prototype.
+
+ * tracepoint.c (_initialize_tracepoint): Do not initialize convenience
+ variables here.
+
2006-01-29 Mark Kettenis <kettenis@gnu.org>
* amd64-tdep.c (amd64_classify): Handle TYPE_CODE_BOOL.
diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 3ac4697..932d724 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -697,7 +697,7 @@ gdb_stat_h = gdb_stat.h
gdb_string_h = gdb_string.h
gdb_thread_db_h = gdb_thread_db.h
gdbthread_h = gdbthread.h $(breakpoint_h) $(frame_h)
-gdbtypes_h = gdbtypes.h
+gdbtypes_h = gdbtypes.h $(hashtab_h)
gdb_vfork_h = gdb_vfork.h
gdb_wait_h = gdb_wait.h
glibc_tdep_h = glibc-tdep.h
@@ -1984,7 +1984,7 @@ gdb-events.o: gdb-events.c $(defs_h) $(gdb_events_h) $(gdbcmd_h)
gdbtypes.o: gdbtypes.c $(defs_h) $(gdb_string_h) $(bfd_h) $(symtab_h) \
$(symfile_h) $(objfiles_h) $(gdbtypes_h) $(expression_h) \
$(language_h) $(target_h) $(value_h) $(demangle_h) $(complaints_h) \
- $(gdbcmd_h) $(wrapper_h) $(cp_abi_h) $(gdb_assert_h)
+ $(gdbcmd_h) $(wrapper_h) $(cp_abi_h) $(gdb_assert_h) $(hashtab_h)
glibc-tdep.o: glibc-tdep.c $(defs_h) $(frame_h) $(symtab_h) $(symfile_h) \
$(objfiles_h) $(glibc_tdep_h)
gnu-nat.o: gnu-nat.c $(gdb_string_h) $(defs_h) $(inferior_h) $(symtab_h) \
@@ -2720,7 +2720,7 @@ utils.o: utils.c $(defs_h) $(gdb_assert_h) $(gdb_string_h) $(event_top_h) \
$(exceptions_h) $(tui_h) $(gdbcmd_h) $(serial_h) $(bfd_h) \
$(target_h) $(demangle_h) $(expression_h) $(language_h) $(charset_h) \
$(annotate_h) $(filenames_h) $(symfile_h) $(inferior_h) \
- $(gdb_curses_h) $(readline_h)
+ $(gdb_curses_h) $(readline_h) $(gdb_obstack_h)
uw-thread.o: uw-thread.c $(defs_h) $(gdbthread_h) $(target_h) $(inferior_h) \
$(regcache_h) $(gregset_h)
v850-tdep.o: v850-tdep.c $(defs_h) $(frame_h) $(frame_base_h) $(trad_frame_h) \
diff --git a/gdb/defs.h b/gdb/defs.h
index 86a0b67..6d4e922 100644
--- a/gdb/defs.h
+++ b/gdb/defs.h
@@ -1217,4 +1217,9 @@ extern int use_windows;
extern ULONGEST align_up (ULONGEST v, int n);
extern ULONGEST align_down (ULONGEST v, int n);
+/* Allocation and deallocation functions for the libiberty hash table
+ which use obstacks. */
+void *hashtab_obstack_allocate (void *data, size_t size, size_t count);
+void dummy_obstack_deallocate (void *object, void *data);
+
#endif /* #ifndef DEFS_H */
diff --git a/gdb/doc/ChangeLog b/gdb/doc/ChangeLog
index a03ae63..530324c 100644
--- a/gdb/doc/ChangeLog
+++ b/gdb/doc/ChangeLog
@@ -1,3 +1,8 @@
+2006-02-01 Daniel Jacobowitz <dan@codesourcery.com>
+
+ * gdb.texinfo (Files): Remove obsolete bits from the description
+ of "symbol-file".
+
2006-01-25 Jim Blandy <jimb@redhat.com>
* gdbint.texinfo (Testsuite): Explain how to run selected tests.
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index fd1a7ed..b2c5de6 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -11094,11 +11094,11 @@ table and program to run from the same file.
@code{symbol-file} with no argument clears out @value{GDBN} information on your
program's symbol table.
-The @code{symbol-file} command causes @value{GDBN} to forget the contents
-of its convenience variables, the value history, and all breakpoints and
-auto-display expressions. This is because they may contain pointers to
-the internal data recording symbols and data types, which are part of
-the old symbol table data being discarded inside @value{GDBN}.
+The @code{symbol-file} command causes @value{GDBN} to forget the contents of
+some breakpoints and auto-display expressions. This is because they may
+contain pointers to the internal data recording symbols and data types,
+which are part of the old symbol table data being discarded inside
+@value{GDBN}.
@code{symbol-file} does not repeat if you press @key{RET} again after
executing it once.
diff --git a/gdb/dwarf2read.c b/gdb/dwarf2read.c
index 943f304..85152a3 100644
--- a/gdb/dwarf2read.c
+++ b/gdb/dwarf2read.c
@@ -1030,10 +1030,6 @@ static gdb_byte *skip_one_die (gdb_byte *info_ptr, struct abbrev_info *abbrev,
static void free_stack_comp_unit (void *);
-static void *hashtab_obstack_allocate (void *data, size_t size, size_t count);
-
-static void dummy_obstack_deallocate (void *object, void *data);
-
static hashval_t partial_die_hash (const void *item);
static int partial_die_eq (const void *item_lhs, const void *item_rhs);
@@ -4627,7 +4623,7 @@ read_subroutine_type (struct die_info *die, struct dwarf2_cu *cu)
/* Allocate storage for parameters and fill them in. */
TYPE_NFIELDS (ftype) = nparams;
TYPE_FIELDS (ftype) = (struct field *)
- TYPE_ALLOC (ftype, nparams * sizeof (struct field));
+ TYPE_ZALLOC (ftype, nparams * sizeof (struct field));
child_die = die->child;
while (child_die && child_die->tag)
@@ -9622,28 +9618,6 @@ dwarf2_clear_marks (struct dwarf2_per_cu_data *per_cu)
}
}
-/* Allocation function for the libiberty hash table which uses an
- obstack. */
-
-static void *
-hashtab_obstack_allocate (void *data, size_t size, size_t count)
-{
- unsigned int total = size * count;
- void *ptr = obstack_alloc ((struct obstack *) data, total);
- memset (ptr, 0, total);
- return ptr;
-}
-
-/* Trivial deallocation function for the libiberty splay tree and hash
- table - don't deallocate anything. Rely on later deletion of the
- obstack. */
-
-static void
-dummy_obstack_deallocate (void *object, void *data)
-{
- return;
-}
-
/* Trivial hash function for partial_die_info: the hash value of a DIE
is its offset in .debug_info for this objfile. */
diff --git a/gdb/gdbtypes.c b/gdb/gdbtypes.c
index b4062b7..dde327b 100644
--- a/gdb/gdbtypes.c
+++ b/gdb/gdbtypes.c
@@ -1,7 +1,7 @@
/* Support routines for manipulating internal types for GDB.
Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002,
- 2003, 2004, 2006 Free Software Foundation, Inc.
+ 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
Contributed by Cygnus Support, using pieces from other GDB modules.
@@ -39,6 +39,7 @@
#include "wrapper.h"
#include "cp-abi.h"
#include "gdb_assert.h"
+#include "hashtab.h"
/* These variables point to the objects
representing the predefined C data types. */
@@ -3152,7 +3153,147 @@ recursive_dump_type (struct type *type, int spaces)
obstack_free (&dont_print_type_obstack, NULL);
}
-static void build_gdbtypes (void);
+/* Trivial helpers for the libiberty hash table, for mapping one
+ type to another. */
+
+struct type_pair
+{
+ struct type *old, *new;
+};
+
+static hashval_t
+type_pair_hash (const void *item)
+{
+ const struct type_pair *pair = item;
+ return htab_hash_pointer (pair->old);
+}
+
+static int
+type_pair_eq (const void *item_lhs, const void *item_rhs)
+{
+ const struct type_pair *lhs = item_lhs, *rhs = item_rhs;
+ return lhs->old == rhs->old;
+}
+
+/* Allocate the hash table used by copy_type_recursive to walk
+ types without duplicates. We use OBJFILE's obstack, because
+ OBJFILE is about to be deleted. */
+
+htab_t
+create_copied_types_hash (struct objfile *objfile)
+{
+ return htab_create_alloc_ex (1, type_pair_hash, type_pair_eq,
+ NULL, &objfile->objfile_obstack,
+ hashtab_obstack_allocate,
+ dummy_obstack_deallocate);
+}
+
+/* Recursively copy (deep copy) TYPE, if it is associated with OBJFILE.
+ Return a new type allocated using malloc, a saved type if we have already
+ visited TYPE (using COPIED_TYPES), or TYPE if it is not associated with
+ OBJFILE. */
+
+struct type *
+copy_type_recursive (struct objfile *objfile, struct type *type,
+ htab_t copied_types)
+{
+ struct type_pair *stored, pair;
+ void **slot;
+ struct type *new_type;
+
+ if (TYPE_OBJFILE (type) == NULL)
+ return type;
+
+ /* This type shouldn't be pointing to any types in other objfiles; if
+ it did, the type might disappear unexpectedly. */
+ gdb_assert (TYPE_OBJFILE (type) == objfile);
+
+ pair.old = type;
+ slot = htab_find_slot (copied_types, &pair, INSERT);
+ if (*slot != NULL)
+ return ((struct type_pair *) *slot)->new;
+
+ new_type = alloc_type (NULL);
+
+ /* We must add the new type to the hash table immediately, in case
+ we encounter this type again during a recursive call below. */
+ stored = xmalloc (sizeof (struct type_pair));
+ stored->old = type;
+ stored->new = new_type;
+ *slot = stored;
+
+ /* Copy the common fields of types. */
+ TYPE_CODE (new_type) = TYPE_CODE (type);
+ TYPE_ARRAY_UPPER_BOUND_TYPE (new_type) = TYPE_ARRAY_UPPER_BOUND_TYPE (type);
+ TYPE_ARRAY_LOWER_BOUND_TYPE (new_type) = TYPE_ARRAY_LOWER_BOUND_TYPE (type);
+ if (TYPE_NAME (type))
+ TYPE_NAME (new_type) = xstrdup (TYPE_NAME (type));
+ if (TYPE_TAG_NAME (type))
+ TYPE_TAG_NAME (new_type) = xstrdup (TYPE_TAG_NAME (type));
+ TYPE_FLAGS (new_type) = TYPE_FLAGS (type);
+ TYPE_VPTR_FIELDNO (new_type) = TYPE_VPTR_FIELDNO (type);
+
+ TYPE_INSTANCE_FLAGS (new_type) = TYPE_INSTANCE_FLAGS (type);
+ TYPE_LENGTH (new_type) = TYPE_LENGTH (type);
+
+ /* Copy the fields. */
+ TYPE_NFIELDS (new_type) = TYPE_NFIELDS (type);
+ if (TYPE_NFIELDS (type))
+ {
+ int i, nfields;
+
+ nfields = TYPE_NFIELDS (type);
+ TYPE_FIELDS (new_type) = xmalloc (sizeof (struct field) * nfields);
+ for (i = 0; i < nfields; i++)
+ {
+ TYPE_FIELD_ARTIFICIAL (new_type, i) = TYPE_FIELD_ARTIFICIAL (type, i);
+ TYPE_FIELD_BITSIZE (new_type, i) = TYPE_FIELD_BITSIZE (type, i);
+ if (TYPE_FIELD_TYPE (type, i))
+ TYPE_FIELD_TYPE (new_type, i)
+ = copy_type_recursive (objfile, TYPE_FIELD_TYPE (type, i),
+ copied_types);
+ if (TYPE_FIELD_NAME (type, i))
+ TYPE_FIELD_NAME (new_type, i) = xstrdup (TYPE_FIELD_NAME (type, i));
+ if (TYPE_FIELD_STATIC_HAS_ADDR (type, i))
+ SET_FIELD_PHYSADDR (TYPE_FIELD (new_type, i),
+ TYPE_FIELD_STATIC_PHYSADDR (type, i));
+ else if (TYPE_FIELD_STATIC (type, i))
+ SET_FIELD_PHYSNAME (TYPE_FIELD (new_type, i),
+ xstrdup (TYPE_FIELD_STATIC_PHYSNAME (type, i)));
+ else
+ {
+ TYPE_FIELD_BITPOS (new_type, i) = TYPE_FIELD_BITPOS (type, i);
+ TYPE_FIELD_STATIC_KIND (new_type, i) = 0;
+ }
+ }
+ }
+
+ /* Copy pointers to other types. */
+ if (TYPE_TARGET_TYPE (type))
+ TYPE_TARGET_TYPE (new_type) = copy_type_recursive (objfile,
+ TYPE_TARGET_TYPE (type),
+ copied_types);
+ if (TYPE_VPTR_BASETYPE (type))
+ TYPE_VPTR_BASETYPE (new_type) = copy_type_recursive (objfile,
+ TYPE_VPTR_BASETYPE (type),
+ copied_types);
+ /* Maybe copy the type_specific bits.
+
+ NOTE drow/2005-12-09: We do not copy the C++-specific bits like
+ base classes and methods. There's no fundamental reason why we
+ can't, but at the moment it is not needed. */
+
+ if (TYPE_CODE (type) == TYPE_CODE_FLT)
+ TYPE_FLOATFORMAT (new_type) == TYPE_FLOATFORMAT (type);
+ else if (TYPE_CODE (type) == TYPE_CODE_STRUCT
+ || TYPE_CODE (type) == TYPE_CODE_UNION
+ || TYPE_CODE (type) == TYPE_CODE_TEMPLATE
+ || TYPE_CODE (type) == TYPE_CODE_NAMESPACE)
+ INIT_CPLUS_SPECIFIC (new_type);
+
+ return new_type;
+}
+
static void
build_gdbtypes (void)
{
diff --git a/gdb/gdbtypes.h b/gdb/gdbtypes.h
index de451d5..944e5f1 100644
--- a/gdb/gdbtypes.h
+++ b/gdb/gdbtypes.h
@@ -25,6 +25,8 @@
#if !defined (GDBTYPES_H)
#define GDBTYPES_H 1
+#include "hashtab.h"
+
/* Forward declarations for prototypes. */
struct field;
struct block;
@@ -1176,6 +1178,12 @@ extern struct type *builtin_type_f_void;
? obstack_alloc (&TYPE_OBJFILE (t) -> objfile_obstack, size) \
: xmalloc (size))
+#define TYPE_ZALLOC(t,size) \
+ (TYPE_OBJFILE (t) != NULL \
+ ? memset (obstack_alloc (&TYPE_OBJFILE (t)->objfile_obstack, size), \
+ 0, size) \
+ : xzalloc (size))
+
extern struct type *alloc_type (struct objfile *);
extern struct type *init_type (enum type_code, int, int, char *,
@@ -1371,4 +1379,10 @@ extern int is_integral_type (struct type *);
extern void maintenance_print_type (char *, int);
+extern htab_t create_copied_types_hash (struct objfile *objfile);
+
+extern struct type *copy_type_recursive (struct objfile *objfile,
+ struct type *type,
+ htab_t copied_types);
+
#endif /* GDBTYPES_H */
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 41aab64..3419c6d 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -393,6 +393,10 @@ free_objfile (struct objfile *objfile)
objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
}
+ /* Remove any references to this objfile in the global value
+ lists. */
+ preserve_values (objfile);
+
/* First do any symbol file specific actions required when we are
finished with a particular symbol file. Note that if the objfile
is using reusable symbol information (via mmalloc) then each of
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 63dd4b3..93cb009 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -2013,6 +2013,10 @@ reread_symbols (void)
memcpy (offsets, objfile->section_offsets,
SIZEOF_N_SECTION_OFFSETS (num_offsets));
+ /* Remove any references to this objfile in the global
+ value lists. */
+ preserve_values (objfile);
+
/* Nuke all the state that we will re-read. Much of the following
code which sets things to NULL really is necessary to tell
other parts of GDB that there is nothing currently there. */
@@ -2485,9 +2489,7 @@ clear_symtab_users (void)
breakpoint_re_set may try to access the current symtab. */
clear_current_source_symtab_and_line ();
- clear_value_history ();
clear_displays ();
- clear_internalvars ();
breakpoint_re_set ();
set_default_breakpoint (0, 0, 0, 0);
clear_pc_function_cache ();
diff --git a/gdb/tracepoint.c b/gdb/tracepoint.c
index 0737e64..c40b120 100644
--- a/gdb/tracepoint.c
+++ b/gdb/tracepoint.c
@@ -2694,11 +2694,6 @@ _initialize_tracepoint (void)
traceframe_number = -1;
tracepoint_number = -1;
- set_internalvar (lookup_internalvar ("tpnum"),
- value_from_longest (builtin_type_int, (LONGEST) 0));
- set_internalvar (lookup_internalvar ("trace_frame"),
- value_from_longest (builtin_type_int, (LONGEST) - 1));
-
if (tracepoint_list.list == NULL)
{
tracepoint_list.listsize = 128;
diff --git a/gdb/utils.c b/gdb/utils.c
index eb870ac..fdebbdc 100644
--- a/gdb/utils.c
+++ b/gdb/utils.c
@@ -53,6 +53,7 @@
#include "annotate.h"
#include "filenames.h"
#include "symfile.h"
+#include "gdb_obstack.h"
#include "inferior.h" /* for signed_pointer_to_address */
@@ -3124,3 +3125,26 @@ align_down (ULONGEST v, int n)
gdb_assert (n && (n & (n-1)) == 0);
return (v & -n);
}
+
+/* Allocation function for the libiberty hash table which uses an
+ obstack. The obstack is passed as DATA. */
+
+void *
+hashtab_obstack_allocate (void *data, size_t size, size_t count)
+{
+ unsigned int total = size * count;
+ void *ptr = obstack_alloc ((struct obstack *) data, total);
+ memset (ptr, 0, total);
+ return ptr;
+}
+
+/* Trivial deallocation function for the libiberty splay tree and hash
+ table - don't deallocate anything. Rely on later deletion of the
+ obstack. DATA will be the obstack, although it is not needed
+ here. */
+
+void
+dummy_obstack_deallocate (void *object, void *data)
+{
+ return;
+}
diff --git a/gdb/value.c b/gdb/value.c
index 801874b..2e30485 100644
--- a/gdb/value.c
+++ b/gdb/value.c
@@ -653,29 +653,6 @@ access_value_history (int num)
return value_copy (chunk->values[absnum % VALUE_HISTORY_CHUNK]);
}
-/* Clear the value history entirely.
- Must be done when new symbol tables are loaded,
- because the type pointers become invalid. */
-
-void
-clear_value_history (void)
-{
- struct value_history_chunk *next;
- int i;
- struct value *val;
-
- while (value_history_chain)
- {
- for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
- if ((val = value_history_chain->values[i]) != NULL)
- xfree (val);
- next = value_history_chain->next;
- xfree (value_history_chain);
- value_history_chain = next;
- }
- value_history_count = 0;
-}
-
static void
show_values (char *num_exp, int from_tty)
{
@@ -842,22 +819,49 @@ internalvar_name (struct internalvar *var)
return var->name;
}
-/* Free all internalvars. Done when new symtabs are loaded,
- because that makes the values invalid. */
+/* Update VALUE before discarding OBJFILE. COPIED_TYPES is used to
+ prevent cycles / duplicates. */
+
+static void
+preserve_one_value (struct value *value, struct objfile *objfile,
+ htab_t copied_types)
+{
+ if (TYPE_OBJFILE (value->type) == objfile)
+ value->type = copy_type_recursive (objfile, value->type, copied_types);
+
+ if (TYPE_OBJFILE (value->enclosing_type) == objfile)
+ value->enclosing_type = copy_type_recursive (objfile,
+ value->enclosing_type,
+ copied_types);
+}
+
+/* Update the internal variables and value history when OBJFILE is
+ discarded; we must copy the types out of the objfile. New global types
+ will be created for every convenience variable which currently points to
+ this objfile's types, and the convenience variables will be adjusted to
+ use the new global types. */
void
-clear_internalvars (void)
+preserve_values (struct objfile *objfile)
{
+ htab_t copied_types;
+ struct value_history_chunk *cur;
struct internalvar *var;
+ int i;
- while (internalvars)
- {
- var = internalvars;
- internalvars = var->next;
- xfree (var->name);
- xfree (var->value);
- xfree (var);
- }
+ /* Create the hash table. We allocate on the objfile's obstack, since
+ it is soon to be deleted. */
+ copied_types = create_copied_types_hash (objfile);
+
+ for (cur = value_history_chain; cur; cur = cur->next)
+ for (i = 0; i < VALUE_HISTORY_CHUNK; i++)
+ if (cur->values[i])
+ preserve_one_value (cur->values[i], objfile, copied_types);
+
+ for (var = internalvars; var; var = var->next)
+ preserve_one_value (var->value, objfile, copied_types);
+
+ htab_delete (copied_types);
}
static void
diff --git a/gdb/value.h b/gdb/value.h
index 6b2216b..e197235 100644
--- a/gdb/value.h
+++ b/gdb/value.h
@@ -502,9 +502,7 @@ extern void typedef_print (struct type *type, struct symbol *news,
extern char *internalvar_name (struct internalvar *var);
-extern void clear_value_history (void);
-
-extern void clear_internalvars (void);
+extern void preserve_values (struct objfile *);
/* From values.c */