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