diff -r 000000000000 -r aa1a9fbd6eb8 patches/gdb/6.3/740-debian_make-cv-type-crash.patch --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/patches/gdb/6.3/740-debian_make-cv-type-crash.patch Thu May 17 16:22:51 2007 +0000 @@ -0,0 +1,132 @@ +2004-11-04 Jim Blandy + + * 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)