When copying a type from a source CTF container to a destination container,

ctf_add_type() first performs a by-name lookup of the type in the
destination container. If this lookup returns a forward declaration for an
enum, struct, or union, reset dst_type back to CTF_ERR, indicating that the
source type is not in fact present in the destination container. This
ensures that ctf_add_type() will also search the destination container's
dynamic type list for the source type.

Without this change, a pair of mutually recursive struct definitions could
cause infinite recursion in ctf_add_type() if the destination container
only contained forward declarations for the struct types: ctf_add_type()
recursively calls itself on each struct member's type, and the forward
declarations meant that the dynamic type list search would be skipped.

MFC after:	2 weeks
Sponsored by:	EMC / Isilon Storage Division
This commit is contained in:
markj 2015-03-11 00:01:39 +00:00
parent a76e348a4b
commit 1c0a61aa61

View File

@ -1313,10 +1313,13 @@ ctf_add_type(ctf_file_t *dst_fp, ctf_file_t *src_fp, ctf_id_t src_type)
* unless dst_type is a forward declaration and src_type is a struct,
* union, or enum (i.e. the definition of the previous forward decl).
*/
if (dst_type != CTF_ERR && dst_kind != kind && (
dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM &&
kind != CTF_K_STRUCT && kind != CTF_K_UNION)))
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
if (dst_type != CTF_ERR && dst_kind != kind) {
if (dst_kind != CTF_K_FORWARD || (kind != CTF_K_ENUM &&
kind != CTF_K_STRUCT && kind != CTF_K_UNION))
return (ctf_set_errno(dst_fp, ECTF_CONFLICT));
else
dst_type = CTF_ERR;
}
/*
* If the non-empty name was not found in the appropriate hash, search