add gdb-client to run on host to debug target.. (kgdb)
[openwrt.git] / toolchain / gdb / patches / 740-debian_make-cv-type-crash.patch
diff --git a/toolchain/gdb/patches/740-debian_make-cv-type-crash.patch b/toolchain/gdb/patches/740-debian_make-cv-type-crash.patch
new file mode 100644 (file)
index 0000000..4e0b8cd
--- /dev/null
@@ -0,0 +1,132 @@
+2004-11-04  Jim Blandy  <jimb@redhat.com>
+
+       * gdbtypes.c (make_qualified_type): Doc fix.  Add assertion to
+       prevent cross-objfile references.
+       (make_cv_type): Doc fix.  Don't create cross-objfile references,
+       even for stub types.
+       (replace_type): Add assertion to prevent cross-objfile references.
+       (check_typedef): Never resolve a stub type by copying over a type
+       from another file.
+
+Index: src/gdb/gdbtypes.c
+===================================================================
+RCS file: /big/fsf/rsync/src-cvs/src/gdb/gdbtypes.c,v
+retrieving revision 1.92
+retrieving revision 1.93
+diff -u -p -r1.92 -r1.93
+--- src/gdb/gdbtypes.c 8 Aug 2004 17:18:16 -0000       1.92
++++ src/gdb/gdbtypes.c 4 Nov 2004 17:50:16 -0000       1.93
+@@ -433,7 +433,9 @@ address_space_int_to_name (int space_fla
+ }
+ /* Create a new type with instance flags NEW_FLAGS, based on TYPE.
+-   If STORAGE is non-NULL, create the new type instance there.  */
++
++   If STORAGE is non-NULL, create the new type instance there.
++   STORAGE must be in the same obstack as TYPE.  */
+ static struct type *
+ make_qualified_type (struct type *type, int new_flags,
+@@ -453,6 +455,12 @@ make_qualified_type (struct type *type, 
+     ntype = alloc_type_instance (type);
+   else
+     {
++      /* If STORAGE was provided, it had better be in the same objfile as
++       TYPE.  Otherwise, we can't link it into TYPE's cv chain: if one
++       objfile is freed and the other kept, we'd have dangling
++       pointers.  */
++      gdb_assert (TYPE_OBJFILE (type) == TYPE_OBJFILE (storage));
++
+       ntype = storage;
+       TYPE_MAIN_TYPE (ntype) = TYPE_MAIN_TYPE (type);
+       TYPE_CHAIN (ntype) = ntype;
+@@ -501,11 +509,12 @@ make_type_with_address_space (struct typ
+    CNST is a flag for setting the const attribute
+    VOLTL is a flag for setting the volatile attribute
+    TYPE is the base type whose variant we are creating.
+-   TYPEPTR, if nonzero, points
+-   to a pointer to memory where the reference type should be stored.
+-   If *TYPEPTR is zero, update it to point to the reference type we return.
+-   We allocate new memory if needed.  */
++   If TYPEPTR and *TYPEPTR are non-zero, then *TYPEPTR points to
++   storage to hold the new qualified type; *TYPEPTR and TYPE must be
++   in the same objfile.  Otherwise, allocate fresh memory for the new
++   type whereever TYPE lives.  If TYPEPTR is non-zero, set it to the
++   new type we construct.  */
+ struct type *
+ make_cv_type (int cnst, int voltl, struct type *type, struct type **typeptr)
+ {
+@@ -524,20 +533,19 @@ make_cv_type (int cnst, int voltl, struc
+   if (typeptr && *typeptr != NULL)
+     {
+-      /* Objfile is per-core-type.  This const-qualified type had best
+-       belong to the same objfile as the type it is qualifying, unless
+-       we are overwriting a stub type, in which case the safest thing
+-       to do is to copy the core type into the new objfile.  */
+-
+-      gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type)
+-                || TYPE_STUB (*typeptr));
+-      if (TYPE_OBJFILE (*typeptr) != TYPE_OBJFILE (type))
+-      {
+-        TYPE_MAIN_TYPE (*typeptr)
+-          = TYPE_ALLOC (*typeptr, sizeof (struct main_type));
+-        *TYPE_MAIN_TYPE (*typeptr)
+-          = *TYPE_MAIN_TYPE (type);
+-      }
++      /* TYPE and *TYPEPTR must be in the same objfile.  We can't have
++       a C-V variant chain that threads across objfiles: if one
++       objfile gets freed, then the other has a broken C-V chain.
++
++       This code used to try to copy over the main type from TYPE to
++       *TYPEPTR if they were in different objfiles, but that's
++       wrong, too: TYPE may have a field list or member function
++       lists, which refer to types of their own, etc. etc.  The
++       whole shebang would need to be copied over recursively; you
++       can't have inter-objfile pointers.  The only thing to do is
++       to leave stub types as stub types, and look them up afresh by
++       name each time you encounter them.  */
++      gdb_assert (TYPE_OBJFILE (*typeptr) == TYPE_OBJFILE (type));
+     }
+   
+   ntype = make_qualified_type (type, new_flags, typeptr ? *typeptr : NULL);
+@@ -562,6 +570,12 @@ replace_type (struct type *ntype, struct
+ {
+   struct type *chain;
++  /* These two types had better be in the same objfile.  Otherwise,
++     the assignment of one type's main type structure to the other
++     will produce a type with references to objects (names; field
++     lists; etc.) allocated on an objfile other than its own.  */
++  gdb_assert (TYPE_OBJFILE (ntype) == TYPE_OBJFILE (ntype));
++
+   *TYPE_MAIN_TYPE (ntype) = *TYPE_MAIN_TYPE (type);
+   /* The type length is not a part of the main type.  Update it for each
+@@ -1416,8 +1430,24 @@ check_typedef (struct type *type)
+         return type;
+       }
+       newtype = lookup_transparent_type (name);
++
+       if (newtype)
+-      make_cv_type (is_const, is_volatile, newtype, &type);
++      {
++        /* If the resolved type and the stub are in the same objfile,
++           then replace the stub type with the real deal.  But if
++           they're in separate objfiles, leave the stub alone; we'll
++           just look up the transparent type every time we call
++           check_typedef.  We can't create pointers between types
++           allocated to different objfiles, since they may have
++           different lifetimes.  Trying to copy NEWTYPE over to TYPE's
++           objfile is pointless, too, since you'll have to move over any
++           other types NEWTYPE refers to, which could be an unbounded
++           amount of stuff.  */
++        if (TYPE_OBJFILE (newtype) == TYPE_OBJFILE (type))
++          make_cv_type (is_const, is_volatile, newtype, &type);
++        else
++          type = newtype;
++      }
+     }
+   /* Otherwise, rely on the stub flag being set for opaque/stubbed types */
+   else if (TYPE_STUB (type) && !currently_reading_symtab)
This page took 0.031998 seconds and 4 git commands to generate.